Repository
OCA/calendar · module folder · Try on Runboat
Module version
Category
Appointments
Folder size
1.18 MB
License
AGPL-3
Application
Yes
Auto-installable
No
Website
https://github.com/OCA/calendar
Last tracking update
2026-08-17 18:05:57
Authors
Odoo Community Association (OCA), Tecnativa
Maintainers
Odoo Community Association (OCA), Tecnativa
Committers
Don Kendall, Weblate, OCA-git-bot, oca-ci, thierry-cmd
Odoo dependencies
Python dependencies
cssselect
System dependencies
None
Required by
sale_resource_booking, survey_resource_booking
Description
This module adds a new app to allow you to book resource combinations in
given schedules.

Example use cases:

- Management of consultations in a clinic.
- Salesman appointments.
- Classroom and projector reservations.
- Hotel room booking.

Among the things you can do:

- Specify the type of booking, which includes a calendar of
  availability.
- Specify which resources can be booked together. All of them must be
  free to be booked.
- Place pending bookings, effectively giving permissions to someone to
  see the availability calendar and choose one slot.
- Partners can do that from their portals.
- If a partner has no user, he can still do the same via a tokenized
  URL.
- Backend users can also do that from the backend.
- Booking lifecycle with computed states.
- Automatic meeting creation and deletion.
- Automatic conflict detection.
- Deadline to block modifications.

Code Analysis

Views touched (23)
XML IDNameModelTypeStatus
alert_availability_lost Alert Resource Booking Availability was Lost ir.ui.view qweb New
mail_activity_schedule_view_form mail.activity.schedule.inherit.calendar mail.activity.schedule calendar Inherits mail.mail_activity_schedule_view_form
mail_activity_view_form_popup mail.activity.form.inherit.booking mail.activity form Inherits mail.mail_activity_view_form_popup
message_combination_assigned message_combination_assigned ir.ui.view qweb New
portal_breadcrumbs portal_breadcrumbs ir.ui.view qweb Inherits portal.portal_breadcrumbs
portal_my_bookings My Bookings ir.ui.view qweb New
portal_my_home portal_my_home ir.ui.view qweb Inherits portal.portal_my_home
resource_booking_combination_view_form Resource booking combination form resource.booking.combination form New
resource_booking_combination_view_search resource.booking.combination.view.search resource.booking.combination search New
resource_booking_combination_view_tree Resource booking combination list resource.booking.combination list New
resource_booking_portal_form Booking portal form ir.ui.view qweb New
resource_booking_portal_header Resource Booking Header ir.ui.view qweb New
resource_booking_portal_schedule Resource Booking Scheduling ir.ui.view qweb New
resource_booking_type_view_form Resource booking type form resource.booking.type form New
resource_booking_type_view_search resource.booking.type.view.search resource.booking.type search New
resource_booking_type_view_tree Resource booking type list resource.booking.type list New
resource_booking_view_calendar Resource booking calendar resource.booking calendar New
resource_booking_view_form Resource booking form resource.booking form New
resource_booking_view_search resource.booking.view.search resource.booking search New
resource_booking_view_tree Resource booking list resource.booking list New
scheduling_calendar Resource Booking Calendar ir.ui.view qweb New
view_calendar_event_form calendar.event.view.form.inherit calendar.event form Inherits calendar.view_calendar_event_form
view_partner_form res.partner form Inherits base.view_partner_form
HTTP endpoints (5)
Route(s)HandlerAuthTypeMethodsFlags
/my/bookings/<int:booking_id>/cancel CustomerPortal.portal_booking_cancel public http ALL website
/my/bookings/<int:booking_id>/confirm CustomerPortal.portal_booking_confirm public http ALL website
/my/bookings/<int:booking_id> CustomerPortal.portal_booking_page public http ALL website
/my/bookings/<int:booking_id>/schedule, /my/bookings/<int:booking_id>/schedule/<int:year>/<int:month> CustomerPortal.portal_booking_schedule public http ALL website
/my/bookings, /my/bookings/page/<int:page> CustomerPortal.portal_my_bookings user http ALL website
Models touched (12)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (1)
  • resource_booking_ids One2many → resource.booking
    comodel_name='resource.booking' inverse_name='meeting_id' string='Resource booking'
Public methods (3)
  • create(self, vals_list)
    @api.model_create_multi
    Transfer resource booking to _attendees_values by context. We need to serialize the creation in that case. mail_notify_author key from context is necessary to force the notification to be sent to author.
  • unlink(self)
    Check you're allowed to unschedule it.
  • write(self, vals)
    Check you're allowed to reschedule it.

New fields (1)
  • booking_id Many2one → resource.booking
    ondelete='cascade' string='Resource booking' args: 'resource.booking'
Public methods (1)
  • action_open_resource_booking(self)

New fields (0)

No new fields.

Public methods (1)
  • action_open_resource_booking(self)

New fields (1)
  • category Selection
    selection_add=[('resource_booking', 'Resource booking')]
Public methods (0)

No public methods.

New fields (2)
  • resource_booking_count Integer
    compute='_compute_resource_booking_count' string='Resource booking count'
  • resource_booking_ids Many2many → resource.booking
    column1='res_partner_id' column2='resource_booking_id' comodel_name='resource.booking' copy=False relation='res_partner_resource_booking_rel' string='Bookings'
Public methods (1)
  • action_view_resource_booking(self)

New fields (21)
  • active Boolean
    default=True
  • booking_activity_ids One2many → mail.activity
    string='Booking Activities' args: 'mail.activity', 'booking_id'
  • categ_ids Many2many → calendar.event.type
    comodel_name='calendar.event.type' string='Tags'
  • combination_auto_assign Boolean
    default=True help='When checked, resource combinations will be (un)assigned automatically based on their availability during the booking dates.' string='Auto assigned'
  • combination_id Many2one → resource.booking.combination
    comodel_name='resource.booking.combination' compute='_compute_combination_id' copy=False domain="[('type_rel_ids.type_id', 'in', [type_id])]" index=True readonly=False store=True string='Resources combination' tracking=True
  • description Html
  • duration Float
    compute='_compute_duration' help='Amount of time that the resources will be booked and unavailable for others.' readonly=False store=True tracking=True
  • is_modifiable Boolean
    compute='_compute_is_modifiable'
  • is_overdue Boolean
    compute='_compute_is_overdue'
  • location Char
    compute='_compute_location' readonly=False store=True
  • meeting_id Many2one → calendar.event
    comodel_name='calendar.event' context={'default_res_id': False, 'default_res_model': False} copy=False help='Meeting confirmed for this booking.' index=True ondelete='set null' string='Meeting'
  • name Char
    help='Leave empty to autogenerate a booking name.' index=True
  • partner_id Many2one → res.partner
    comodel_name='res.partner' compute='_compute_partner_id' inverse='_inverse_partner_id' readonly=False search='_search_partner_id' string='Requester'
  • partner_ids Many2many → res.partner
    comodel_name='res.partner' help='Who will attend this booking?' relation='res_partner_resource_booking_rel' required=True string='Attendees' tracking=True
  • requester_advice Text
    readonly=True related='type_id.requester_advice'
  • start Datetime
    compute='_compute_start' copy=False index=True readonly=False store=True tracking=True
  • state Selection
    compute='_compute_state' default='pending' help='Pending: No meeting scheduled.\nScheduled: The requester has not confirmed attendance yet.\nConfirmed: Meeting scheduled, and requester attendance confirmed.\nCanceled: Meeting removed, booking archived.' index=True store=True tracking=True args: [('pending', 'Pending'), ('scheduled', 'Scheduled'), ('confirmed', 'Confirmed'), ('canceled', 'Canceled')]
  • stop Datetime
    compute='_compute_stop' copy=False index=True store=True tracking=True
  • type_id Many2one → resource.booking.type
    comodel_name='resource.booking.type' index=True ondelete='cascade' required=True string='Type' tracking=True
  • user_id Many2one → res.users
    comodel_name='res.users' compute='_compute_user_id' default=<expr> help='Who organized this booking? Usually whoever created the record. It will appear as the calendar event organizer, when scheduled, and calendar notifications will be sent in his/her name.' index=True readonly=False store=True string='Organizer' tracking=True
  • videocall_location Char
    compute='_compute_videocall_location' readonly=False store=True string='Meeting URL'
Public methods (8)
  • action_cancel(self)
    Cancel this booking.
  • action_confirm(self)
    Confirm own and requesting partner's attendance.
  • action_open_portal(self)
  • action_schedule(self)
    Redirect user to a simpler way to schedule this booking.
  • action_unschedule(self)
    Remove associated meetings.
  • create(self, vals_list)
    @api.model_create_multi
    Sync booking with meeting if needed.
  • unlink(self)
    Unlink meeting if needed.
  • write(self, vals)
    Sync booking with meeting if needed.

New fields (8)
  • active Boolean
    default=True
  • booking_count Integer
    compute='_compute_booking_count' string='Booking count'
  • booking_ids One2many → resource.booking
    comodel_name='resource.booking' inverse_name='combination_id' string='Bookings'
  • forced_calendar_id Many2one → resource.calendar
    comodel_name='resource.calendar' help="Force a specific calendar, instead of combining the resources'." index=True string='Forced calendar'
  • name Char
    compute='_compute_name' store=True
  • resource_ids Many2many → resource.resource
    comodel_name='resource.resource' help='Resources that must be free to be booked together.' required=True string='Resources'
  • type_count Integer
    compute='_compute_type_count' string='Booking types'
  • type_rel_ids One2many → resource.booking.type.combination.rel
    comodel_name='resource.booking.type.combination.rel' help='Resource booking types where this combination is available.' inverse_name='combination_id' string='Resource booking types'
Public methods (2)
  • action_open_bookings(self)
  • action_open_resource_booking_types(self)

New fields (16)
  • active Boolean
    default=True
  • alarm_ids Many2many → calendar.alarm
    comodel_name='calendar.alarm' help='Meetings will be created with these reminders by default.' string='Default reminders'
  • booking_count Integer
    compute='_compute_booking_count'
  • booking_ids One2many → resource.booking
    comodel_name='resource.booking' help='Bookings available for this type' inverse_name='type_id' string='Bookings'
  • categ_ids Many2many → calendar.event.type
    comodel_name='calendar.event.type' help='Meetings will be created with these tags by default.' string='Default tags'
  • combination_assignment Selection
    default='random' help='Choose how to auto-assign resource combinations. It has no effect if assigned manually.' required=True args: [('sorted', 'Sorted: pick the first one that is free'), ('random', 'Randomly: order is not important')]
  • combination_rel_ids One2many → resource.booking.type.combination.rel
    comodel_name='resource.booking.type.combination.rel' copy=True help='Resource combinations available for this type of bookings.' inverse_name='type_id' string='Available resource combinations'
  • company_id Many2one → res.company
    comodel_name='res.company' default=<expr> help='Company where this booking type is available.' index=True readonly=False store=True string='Company'
  • duration Float
    default=0.5 help='Booking default duration.' required=True
  • location Char
  • modifications_deadline Float
    default=24 help='When this deadline has been exceeded, if a booking was not yet confirmed, it will be canceled automatically. Also, only booking managers will be able to unschedule or reschedule them. The value is expressed in hours.' required=True
  • name Char
    index='trigram' required=True translate=True
  • requester_advice Text
    help='Text that will appear by default in portal invitation emails and in calendar views for scheduling.' translate=True
  • resource_calendar_id Many2one → resource.calendar
    comodel_name='resource.calendar' default=<expr> help='Restrict bookings to this schedule.' index=True ondelete='restrict' required=True string='Availability Calendar'
  • slot_duration Float
    default=0.5 help='Interval offered to start each resource booking.' required=True
  • videocall_location Char
    string='Meeting URL'
Public methods (1)
  • action_open_bookings(self)

New fields (4)
  • combination_id Many2one → resource.booking.combination
    comodel_name='resource.booking.combination' index=True ondelete='cascade' required=True string='Combination'
  • sequence Integer
    default=100 index=True required=True
  • type_id Many2one → resource.booking.type
    comodel_name='resource.booking.type' index=True ondelete='cascade' required=True string='Type'
  • type_name Char
    related='type_id.name'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (1)
  • is_available(self, start_dt, end_dt, domain=None, tz=None)
    Convenience method to check whether a resource is available within a time span.

Loading…

Loading…

Loading…

Loading…

Loading…

Loading…

Loading…