Repository
odoo/odoo · module folder
Module version
1.1
Category
Productivity/Calendar
Folder size
9.57 MB
License
LGPL-3
Application
Yes
Auto-installable
No
Website
None
Last tracking update
2026-08-15 22:44:18
Authors
Odoo S.A.
Maintainers
Odoo S.A.
Committers
Xavier Morel, Raphael Collet, Christophe Simonis, Thibault Delavallée, odoo, Odoo Translation Bot, Aaron Bohy, Jairo Llopis, Lucas Perais, Julien Castiaux, Sébastien Theys, Julien Mougenot, Rémy Voet (ryv), Tiffany Chang (tic), Gorash, Mathieu Duckerts-Antoine, Arnaud Joset, William Braeckman, Didier (did), luvi, Renaud Thiry, tsm-odoo, Louis Wicket (wil), Maximilien (malb), Victor Piryns (pivi), Julien (jula), Thomas Becquevort (thbe), amdi-odoo, Levi Siuzdak (sile), Maruan Aguerdouh (magm), Dylan Kiss (dyki), Mayurrajsinh Rathod, Rahul Prajapati, Noe Antoine, sesn-odoo, aktr-odoo, bary, Maryam Kia, jorv-odoo, reka-odoo, dhba, Bastien Fafchamps (bafa), Gabriel (gdpf), Tanguy Quéguineur, Chrysanthe (chgo), mano-odoo, aamo-odoo, guce, yagp-odoo, Pierre Pulinckx (PIPU), Ezzuldin Zaky (ezza), sben-odoo, st-yes, abdelrahmanfawzy, Pierre Pulinckx, Bastien PIERRE, nikj-odoo, Michaël Mattiello, Jeffrey Luo, kpt-odoo, Samuel Fritz Struble, pish-odoo, Krzysztof Magusiak (krma), krip-odoo, Sylvio Poliart (sypol), Gurpreet Singh, mojem, pajo, Laetitia (ldau), adip-odoo, Yagnik ✗ (yagp), assh-odoo, Kevin Gerard (kege), saurabh, Jan Suhr, alan-odoo, Kadam Darji, Farah (ahmfa), MostafaTwfiq, Julien Carion, ELCO, chpa-odoo, FedericoBraidi, Manoel Malafaia
Odoo dependencies
odoo/odoo:
- web
- bus
Python dependencies
None
System dependencies
None
Required by
calendar_event_type_multi_company, calendar_public_holiday, calendar_sms, crm, crm_phonecall, fieldservice_calendar, google_calendar, hr_calendar, hr_holidays, hr_homeworking_calendar, hr_recruitment, mail_activity_board, microsoft_calendar, pms_sale, resource_booking, test_discuss_full
Description
This is a full-featured calendar system.
========================================

It supports:
------------
    - Calendar of events
    - Recurring events

If you need to manage your meetings, you should install the CRM module.
    

Code Analysis

Views touched (19)
XML IDNameModelTypeStatus
calendar_alarm_view_form calendar.alarm.form calendar.alarm form New
calendar_popover_delete_view calendar.popover.delete.wizard.view.form calendar.popover.delete.wizard form New
calendar_provider_config_view_form calendar.provider.config.view.form calendar.provider.config form New
invitation_page_anonymous Calendar Invitation Page for anonymous users 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.calendar mail.activity calendar Inherits mail.mail_activity_view_form_popup
res_config_settings_view_form res.config.settings.view.form.inherit.calendar res.config.settings calendar Inherits base.res_config_settings_view_form
res_users_form_view res.users.form.calendar res.users calendar Inherits base.view_users_form
res_users_form_view_calendar_default_privacy res.users.preferences.form.inherit res.users form Inherits base.view_users_form_simple_modif
res_users_view_form res.users.view.form.inherit.calendar res.users calendar Inherits base.view_users_form
view_calendar_alarm_tree calendar.alarm.list calendar.alarm list New
view_calendar_event_calendar calendar.event.calendar calendar.event calendar New
view_calendar_event_form calendar.event.form calendar.event form New
view_calendar_event_form_quick_create calendar.event.form.quick_create calendar.event form New
view_calendar_event_search calendar.event.search calendar.event search New
view_calendar_event_tree calendar.event.list calendar.event list New
view_calendar_event_type_tree calendar.event.type calendar.event.type list New
view_event_delete_wizard_form calendar.popover.delete.wizard.form calendar.popover.delete.wizard form New
view_partners_form res_partner.view.form.calendar res.partner calendar Inherits base.view_partner_form
HTTP endpoints (10)
Route(s)HandlerAuthTypeMethodsFlags
/calendar/meeting/accept CalendarController.accept_meeting calendar http ALL sudo
/calendar/recurrence/accept CalendarController.accept_recurrence calendar http ALL sudo
/calendar/meeting/join CalendarController.calendar_join_meeting user http ALL sudo website
/calendar/join_videocall/<string:access_token> CalendarController.calendar_join_videocall public http ALL sudo
/calendar/check_credentials CalendarController.check_calendar_credentials user jsonrpc ALL
/calendar/meeting/decline CalendarController.decline_meeting calendar http ALL sudo
/calendar/recurrence/decline CalendarController.decline_recurrence calendar http ALL sudo
/calendar/notify CalendarController.notify user jsonrpc ALL
/calendar/notify_ack CalendarController.notify_ack user jsonrpc ALL sudo
/calendar/meeting/view CalendarController.view_meeting calendar http ALL sudo
Models touched (18)

New fields (8)
  • alarm_type Selection
    default='email' required=True string='Type' args: [('notification', 'Notification'), ('email', 'Email')]
  • body Text
    help='Additional message that would be sent with the notification for the reminder' args: 'Additional Message'
  • duration Integer
    default=1 required=True args: 'Remind Before'
  • duration_minutes Integer
    compute='_compute_duration_minutes' search='_search_duration_minutes' store=True args: 'Duration in minutes'
  • interval Selection
    default='hours' required=True args: list(_interval_selection.items()), 'Unit'
  • mail_template_id Many2one → mail.template
    compute='_compute_mail_template_id' domain=[('model', 'in', ['calendar.attendee'])] help='Template used to render mail reminder content.' readonly=False store=True string='Email Template' args: 'mail.template'
  • name Char
    required=True translate=True args: 'Name'
  • notify_responsible Boolean
    default=False args: 'Notify Responsible'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (3)
  • do_check_alarm_for_one_date(self, one_date, event, event_maxdelta, in_the_next_X_seconds, alarm_type, after=False, missing=False)
    Search for some alarms in the interval of time determined by some parameters (after, in_the_next_X_seconds, ...) :param one_date: date of the event to check (not the same that in the event browse if recurrent) :param event: Event browse record :param event_maxdelta: biggest duration from alarms for this event :param in_the_next_X_seconds: looking in the future (in seconds) :param after: if not False: will return alert if after this date (date as string - todo: change in master) :param missing: if not False: will return alert even if we are too late :param notif: Looking for type notification :param mail: looking for type email
  • do_notif_reminder(self, alert)
  • get_next_notif(self)
    @api.model

New fields (10)
  • access_token Char
    default=_default_access_token args: 'Invitation Token'
  • availability Selection
    readonly=True args: [('free', 'Available'), ('busy', 'Busy')], 'Available/Busy'
  • common_name Char
    compute='_compute_common_name' store=True args: 'Common name'
  • email Char
    related='partner_id.email' args: 'Email'
  • event_id Many2one → calendar.event
    index=True ondelete='cascade' required=True args: 'calendar.event', 'Meeting linked'
  • mail_tz Selection
    compute='_compute_mail_tz' help='Timezone used for displaying time in the mail template' args: _tz_get
  • partner_id Many2one → res.partner
    ondelete='cascade' readonly=True required=True args: 'res.partner', 'Attendee'
  • phone Char
    related='partner_id.phone' args: 'Phone'
  • recurrence_id Many2one → calendar.recurrence
    related='event_id.recurrence_id' args: 'calendar.recurrence'
  • state Selection
    default='needsAction' string='Status' args: STATE_SELECTION
Public methods (7)
  • copy(self, default=None)
  • create(self, vals_list)
    @api.model_create_multi
  • do_accept(self)
    Marks event invitation as Accepted.
  • do_decline(self)
    Marks event invitation as Declined.
  • do_tentative(self)
    Makes event invitation as Tentative.
  • unlink(self)
  • write(self, vals)

New fields (67)
  • accepted_count Integer
    compute='_compute_attendees_count'
  • access_token Char
    copy=False index=True store=True args: 'Invitation Token'
  • active Boolean
    default=True help='If the active field is set to false, it will allow you to hide the event alarm information without removing it.' tracking=True args: 'Active'
  • activity_ids One2many → mail.activity
    string='Activities' args: 'mail.activity', 'calendar_event_id'
  • alarm_ids Many2many → calendar.alarm
    help='Notifications sent to all attendees to remind of the meeting.' ondelete='restrict' string='Reminders' args: 'calendar.alarm', 'calendar_alarm_calendar_event_rel'
  • allday Boolean
    default=False args: 'All Day'
  • attendee_ids One2many → calendar.attendee
    args: 'calendar.attendee', 'event_id', 'Participant'
  • attendees_count Integer
    compute='_compute_attendees_count'
  • awaiting_count Integer
    compute='_compute_attendees_count'
  • byday Selection
    compute='_compute_recurrence' readonly=False string='By day' args: BYDAY_SELECTION
  • categ_ids Many2many → calendar.event.type
    args: 'calendar.event.type', 'meeting_category_rel', 'event_id', 'type_id', 'Tags'
  • count Integer
    compute='_compute_recurrence' help='Repeat x times' readonly=False string='Number of Repetitions'
  • current_attendee Many2one → calendar.attendee
    compute='_compute_current_attendee' search='_search_current_attendee' args: 'calendar.attendee'
  • current_status Selection
    readonly=False related='current_attendee.state' string='Attending?'
  • day Integer
    compute='_compute_recurrence' readonly=False args: 'Date of month'
  • declined_count Integer
    compute='_compute_attendees_count'
  • description Html
    help='When synchronization with an external calendar is active, this description is synchronized with the one of the associated meeting in that external calendar. Any update will be propagated there and vice versa.' args: 'Description'
  • display_description Boolean
    compute='_compute_display_description'
  • display_time Char
    compute='_compute_display_time' args: 'Event Time'
  • duration Float
    compute='_compute_duration' readonly=False store=True args: 'Duration'
  • effective_privacy Selection
    compute='_compute_effective_privacy' help='Whether the event is private, considering the user privacy' args: [('public', 'Public'), ('private', 'Private'), ('confidential', 'Only internal users')], 'Effective Privacy'
  • end_type Selection
    compute='_compute_recurrence' readonly=False string='Recurrence Termination' args: END_TYPE_SELECTION
  • event_tz Selection
    compute='_compute_recurrence' readonly=False string='Timezone' args: _tz_get
  • follow_recurrence Boolean
    default=False
  • fri Boolean
    compute='_compute_recurrence' readonly=False
  • interval Integer
    compute='_compute_recurrence' help='Repeat every (Days/Week/Month/Year)' readonly=False string='Repeat On'
  • invalid_email_partner_ids Many2many → res.partner
    compute='_compute_invalid_email_partner_ids' args: 'res.partner'
  • is_highlighted Boolean
    compute='_compute_is_highlighted' string='Is the Event Highlighted'
  • is_organizer_alone Boolean
    compute='_compute_is_organizer_alone' help="Check if the organizer is alone in the event, i.e. if the organizer is the only one that hasn't declined\n the event (only if the organizer is not the only attendee)" string='Is the Organizer Alone'
  • location Char
    tracking=True args: 'Location'
  • mon Boolean
    compute='_compute_recurrence' readonly=False
  • month_by Selection
    compute='_compute_recurrence' readonly=False string='Option' args: MONTH_BY_SELECTION
  • name Char
    required=True args: 'Meeting Subject'
  • notes Html
    args: 'Notes'
  • partner_id Many2one → res.partner
    readonly=True related='user_id.partner_id' string='Scheduled by' args: 'res.partner'
  • partner_ids Many2many → res.partner
    default=_default_partners string='Attendees' args: 'res.partner', 'calendar_event_res_partner_rel'
  • privacy Selection
    help='People to whom this event will be visible.' args: [('public', 'Public'), ('private', 'Private'), ('confidential', 'Only internal users')], 'Privacy'
  • recurrence_id Many2one → calendar.recurrence
    index='btree_not_null' string='Recurrence Rule' args: 'calendar.recurrence'
  • recurrence_update Selection
    copy=False default='self_only' help='Choose what to do with other events in the recurrence. Updating All Events is not allowed when dates or time is modified' store=False args: [('self_only', 'This event'), ('future_events', 'This and following events'), ('all_events', 'All events')]
  • recurrency Boolean
    args: 'Recurrent'
  • res_id Many2oneReference
    model_field='res_model' args: 'Document ID'
  • res_model Char
    readonly=True related='res_model_id.model' store=True args: 'Document Model Name'
  • res_model_id Many2one → ir.model
    ondelete='cascade' args: 'ir.model', 'Document Model'
  • res_model_name Char
    related='res_model_id.name'
  • rrule Char
    compute='_compute_recurrence' readonly=False args: 'Recurrent Rule'
  • rrule_type Selection
    compute='_compute_recurrence' help='Let the event automatically repeat at that interval' readonly=False string='Recurrence' args: RRULE_TYPE_SELECTION
  • rrule_type_ui Selection
    compute='_compute_rrule_type_ui' help='Let the event automatically repeat at that interval' readonly=False string='Repeat' args: RRULE_TYPE_SELECTION_UI
  • sat Boolean
    compute='_compute_recurrence' readonly=False
  • should_show_status Boolean
    compute='_compute_should_show_status'
  • show_as Selection
    default='busy' help="If the time is shown as 'busy', this event will be visible to other people with either the full information or simply 'busy' written depending on its privacy. Use this option to let other people know that you are unavailable during that period of time. \n If the event is shown as 'free', other users know that you are available during that period of time." required=True args: [('free', 'Available'), ('busy', 'Busy')], 'Show as'
  • start Datetime
    default=_default_start help='Start date of an event, without time for full days events' index=True required=True tracking=True args: 'Start'
  • start_date Date
    compute='_compute_dates' inverse='_inverse_dates' store=True tracking=True args: 'Start Date'
  • stop Datetime
    compute='_compute_stop' default=_default_stop help='Stop date of an event, without time for full days events' readonly=False required=True store=True tracking=True args: 'Stop'
  • stop_date Date
    compute='_compute_dates' inverse='_inverse_dates' store=True tracking=True args: 'End Date'
  • sun Boolean
    compute='_compute_recurrence' readonly=False
  • tentative_count Integer
    compute='_compute_attendees_count'
  • thu Boolean
    compute='_compute_recurrence' readonly=False
  • tue Boolean
    compute='_compute_recurrence' readonly=False
  • unavailable_partner_ids Many2many → res.partner
    compute='_compute_unavailable_partner_ids' string='Unavailable Attendees' args: 'res.partner'
  • until Date
    compute='_compute_recurrence' readonly=False
  • user_can_edit Boolean
    compute='_compute_user_can_edit'
  • user_id Many2one → res.users
    default=<expr> index='btree_not_null' args: 'res.users', 'Organizer'
  • videocall_channel_id Many2one → discuss.channel
    index='btree_not_null' args: 'discuss.channel', 'Discuss Channel'
  • videocall_location Char
    compute='_compute_videocall_location' copy=True store=True args: 'Meeting URL'
  • videocall_source Selection
    compute='_compute_videocall_source' args: [('discuss', 'Discuss'), ('custom', 'Custom')]
  • wed Boolean
    compute='_compute_recurrence' readonly=False
  • weekday Selection
    compute='_compute_recurrence' readonly=False args: WEEKDAY_SELECTION
Public methods (22)
  • action_join_meeting(self, partner_id)
    Method used when an existing user wants to join
  • action_join_video_call(self)
  • action_mass_archive(self, recurrence_update_setting)
    The aim of this action purpose is to be called from sync calendar module when mass deletion is not possible.
  • action_mass_deletion(self, recurrence_update_setting)
  • action_open_calendar_event(self)
  • action_open_composer(self)
  • action_sendmail(self)
  • action_unlink_event(self, attendee_id=None, recurrence=False)
    Delete the event after displaying the delete wizard if necessary. :param attendee_id: The ID of the attendee for the event :param recurrence: Boolean indicating if the event is recurring :return: Action to delete the event
  • change_attendee_status(self, status, recurrence_update_setting)
  • clear_videocall_location(self)
  • copy(self, default=None)
    When an event is copied, the attendees should be recreated to avoid sharing the same attendee records between copies
  • create(self, vals_list)
    @api.model_create_multi
  • default_get(self, fields)
    @api.model
  • find_partner_customer(self)
  • get_default_duration(self)
    @api.model
  • get_discuss_videocall_location(self)
    @api.model
  • get_display_time_tz(self, tz=False)
    get the display_time of the meeting, forcing the timezone. This method is called from email template, to not use sudo().
  • get_next_alarm_date(self, events_by_alarm)
  • get_state_selections(self)
    @api.model
  • set_discuss_videocall_location(self)
  • unlink(self)
  • write(self, vals)

New fields (2)
  • color Integer
    default=_default_color args: 'Color'
  • name Char
    required=True args: 'Name'
Public methods (0)

No public methods.

New fields (4)
  • active Boolean
    default=True args: 'Active'
  • partner_checked Boolean
    default=True args: 'Checked'
  • partner_id Many2one → res.partner
    index=True required=True args: 'res.partner', 'Employee'
  • user_id Many2one → res.users
    default=<expr> index=True ondelete='cascade' required=True args: 'res.users', 'Me'
Public methods (1)
  • unlink_from_partner_id(self, partner_id)
    @api.model

New fields (3)
  • calendar_event_id Many2one → calendar.event
    args: 'calendar.event', 'Calendar Event'
  • delete Selection
    default='one' args: [('one', 'Delete this event'), ('next', 'Delete this and following events'), ('all', 'Delete all the events')]
  • recipient_ids Many2many → res.partner
    compute='_compute_recipient_ids' readonly=False string='Recipients' args: 'res.partner'
Public methods (3)
  • action_delete(self)
    Delete the event based on the specified deletion type. :return: Action URL to redirect to the calendar view
  • action_send_mail_and_delete(self)
    Send email notification and delete the event based on the specified deletion type.
  • close(self)

New fields (7)
  • cal_client_id Char
    default=<expr> args: 'Google Client_id'
  • cal_client_secret Char
    default=<expr> args: 'Google Client_key'
  • cal_sync_paused Boolean
    default=<expr> args: 'Google Synchronization Paused'
  • external_calendar_provider Selection
    default='google' args: [('google', 'Google'), ('microsoft', 'Outlook')], 'Choose an external calendar to configure'
  • microsoft_outlook_client_identifier Char
    default=<expr> args: 'Outlook Client Id'
  • microsoft_outlook_client_secret Char
    default=<expr> args: 'Outlook Client Secret'
  • microsoft_outlook_sync_paused Boolean
    default=<expr> args: 'Outlook Synchronization Paused'
Public methods (1)
  • action_calendar_prepare_external_provider_sync(self)
    @assert_log_admin_access
    Called by the wizard to configure an external calendar provider without requiring users to access the general settings page. Make sure that the provider calendar module is installed or install it. Then, set the API keys into the applicable config parameters.

New fields (23)
  • base_event_id Many2one → calendar.event
    copy=False ondelete='set null' args: 'calendar.event'
  • byday Selection
    string='By day' args: BYDAY_SELECTION
  • calendar_event_ids One2many → calendar.event
    args: 'calendar.event', 'recurrence_id'
  • count Integer
    default=1
  • day Integer
    default=1
  • dtstart Datetime
    compute='_compute_dtstart'
  • end_type Selection
    default='count' args: END_TYPE_SELECTION
  • event_tz Selection
    default=<expr> string='Timezone' args: _tz_get
  • fri Boolean
  • interval Integer
    default=1
  • mon Boolean
  • month_by Selection
    default='date' args: MONTH_BY_SELECTION
  • name Char
    compute='_compute_name' store=True
  • rrule Char
    compute='_compute_rrule' inverse='_inverse_rrule' store=True
  • rrule_type Selection
    default='weekly' args: RRULE_TYPE_SELECTION
  • sat Boolean
  • sun Boolean
  • thu Boolean
  • trigger_id Many2one → ir.cron.trigger
    args: 'ir.cron.trigger'
  • tue Boolean
  • until Date
    args: 'Repeat Until'
  • wed Boolean
  • weekday Selection
    string='Weekday' args: WEEKDAY_SELECTION
Public methods (1)
  • get_recurrence_name(self)

New fields (1)
  • calendar_event_ids One2many → calendar.event
    args: 'calendar.event', 'videocall_channel_id'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (1)
  • calendar_event_id Many2one → calendar.event
    index='btree_not_null' ondelete='cascade' string='Calendar Meeting' args: 'calendar.event'
Public methods (3)
  • action_create_calendar_event(self)
  • unlink_w_meeting(self)
  • write(self, vals)

New fields (1)
  • activity_calendar_event_id Many2one → calendar.event
    compute='_compute_activity_calendar_event_id' groups='base.group_user' string='Next Activity Calendar Event' args: 'calendar.event'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (1)
  • action_create_calendar_event(self)

New fields (1)
  • category Selection
    selection_add=[('meeting', 'Meeting')]
Public methods (0)

No public methods.

New fields (3)
  • calendar_last_notif_ack Datetime
    default=fields.Datetime.now args: 'Last notification marked as read from base Calendar'
  • meeting_count Integer
    compute='_compute_meeting_count' args: '# Meetings'
  • meeting_ids Many2many → calendar.event
    copy=False string='Meetings' args: 'calendar.event', 'calendar_event_res_partner_rel', 'res_partner_id', 'calendar_event_id'
Public methods (2)
  • get_attendee_detail(self, meeting_ids)
    Return a list of dict of the given meetings with the attendees details Used by: - many2many_attendee.js: Many2ManyAttendee - calendar_model.js (calendar.CalendarModel)
  • schedule_meeting(self)

New fields (1)
  • calendar_default_privacy Selection
    compute='_compute_calendar_default_privacy' inverse='_inverse_calendar_res_users_settings' args: [('public', 'Public by default'), ('private', 'Private by default'), ('confidential', 'Internal users only')]
Public methods (7)
  • SELF_READABLE_FIELDS(self)
    @property
  • SELF_WRITEABLE_FIELDS(self)
    @property
  • check_calendar_credentials(self)
    @api.model
  • check_synchronization_status(self)
  • create(self, vals_list)
    @api.model_create_multi
    Set the calendar default privacy as the same as Default User Template when defined.
  • get_selected_calendars_partner_ids(self, include_user=True)
    Retrieves the partner IDs of the attendees selected in the calendar view. :param bool include_user: Determines whether to include the current user's partner ID in the results. :return: A list of integer IDs representing the partners selected in the calendar view. If 'include_user' is True, the list will also include the current user's partner ID. :rtype: list
  • write(self, vals)
    Forbid the calendar default privacy update from different users for keeping private events secured.

New fields (1)
  • calendar_default_privacy Selection
    default='public' help='Default privacy setting for whom the calendar events will be visible.' readonly=False required=True store=True args: [('public', 'Public'), ('private', 'Private'), ('confidential', 'Only internal users')], 'Calendar Default Privacy'
Public methods (0)

No public methods.

Loading…

Loading…

Loading…

Loading…

Loading…

Loading…

Loading…

Loading…

Loading…

Loading…

Loading…