Calendar

calendar
REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/19.0/calendar
VERSION
VERSION 1.1
CATEGORY
CATEGORYProductivity/Calendar
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONYes
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo S.A.
MAINTAINERS
MAINTAINERSOdoo S.A.
COMMITTERS
COMMITTERSRaphael Collet, Odoo Translation Bot, Thibault Delavallée, Christophe Simonis, Xavier Morel, Aaron Bohy, Jairo Llopis, Lucas Perais, Julien Castiaux, Sébastien Theys, Julien Mougenot, Tiffany Chang (tic), Rémy Voet (ryv), Gorash, Mathieu Duckerts-Antoine, Arnaud Joset, William Braeckman, odoo, Didier (did), luvi, Renaud Thiry, Louis Wicket (wil), tsm-odoo, 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, Bastien Fafchamps (bafa), dhba, Gabriel (gdpf), Tanguy Quéguineur, Chrysanthe (chgo), mano-odoo, aamo-odoo, guce, yagp-odoo, Pierre Pulinckx (PIPU), sben-odoo, Ezzuldin Zaky (ezza), st-yes, abdelrahmanfawzy, Michaël Mattiello, nikj-odoo, Pierre Pulinckx, Bastien PIERRE, Jeffrey Luo, kpt-odoo, Samuel Fritz Struble, pish-odoo, Krzysztof Magusiak (krma), krip-odoo, Gurpreet Singh, pajo, mojem, Laetitia (ldau), adip-odoo, Yagnik ✗ (yagp), assh-odoo, Kevin Gerard (kege), saurabh, alan-odoo, Kadam Darji, Farah (ahmfa), ELCO, MostafaTwfiq, Julien Carion, chpa-odoo, FedericoBraidi, Manoel Malafaia
WEBSITE
WEBSITE
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 01:51:44
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - base
    - mail
    - base_setup
    - web
    - bus
    - web_tour
    - html_editor
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
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 xpath Inherits mail.mail_activity_schedule_view_form
mail_activity_view_form_popup mail.activity.form.inherit.calendar mail.activity xpath Inherits mail.mail_activity_view_form_popup
res_config_settings_view_form res.config.settings.view.form.inherit.calendar res.config.settings xpath Inherits base.res_config_settings_view_form
res_users_form_view res.users.form.calendar res.users xpath Inherits base.view_users_form
res_users_form_view_calendar_default_privacy res.users.preferences.form.inherit res.users xpath Inherits base.view_users_form_simple_modif
res_users_view_form res.users.view.form.inherit.calendar res.users xpath 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 data Inherits base.view_partner_form
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.

REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/18.0/calendar
VERSION
VERSION 1.1
CATEGORY
CATEGORYProductivity/Calendar
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONYes
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORS
MAINTAINERS
MAINTAINERS
COMMITTERS
COMMITTERSRaphael Collet, Odoo Translation Bot, Martin Trigaux, Thibault Delavallée, Xavier Morel, Aaron Bohy, Yannick Tivisse, Odoo Online, Jorge Pinna Puissant, Jairo Llopis, Alexandre Kühn, Julien Castiaux, Aurélien Warnon, Xavier-Do, Romeo Fragomeli, Sébastien Theys, Julien Mougenot, Tiffany Chang (tic), Rémy Voet (ryv), Gorash, Pierre Paridans, Arnaud Joset, William Braeckman, odoo, Víctor Martínez, Didier (did), Florian Charlier, Abdelouahab (abla), Renaud Thiry, Vincent Larcin, damr, Thomas Lefebvre (thle), Louis Wicket (wil), tsm-odoo, nda, Victor Piryns (pivi), Julien (jula), Thomas Becquevort (thbe), amdi-odoo, Levi Siuzdak (sile), Maruan Aguerdouh (magm), Dylan Kiss (dyki), Bruno Boi, Chong Wang (cwg), Brieuc-brd, AH-Yussef, Leonardo Pavan Rocha, Mahdi Cheikh Rouhou (macr), Noe Antoine, omra-odoo, Andrzej(pian), sesn-odoo, aktr-odoo, Mattis Megevand, Mélanie, Youssef Bashandy, lase@odoo.com, bary, Maryam Kia, jorv-odoo, Jérémy Hennecart (jeh), Julien Carion (juca), Gabriel (gdpf), Tanguy Quéguineur, ahmad(alah), Louis (wil), mano-odoo, aamo-odoo, yagp-odoo, Pierre Pulinckx (PIPU), sben-odoo, Ezzuldin Zaky (ezza), st-yes, abdelrahmanfawzy, Gabriel de Paula Felix (gdpf), Khushi, Michaël Mattiello, nikj-odoo, Pierre Pulinckx (pipu), Bastien PIERRE, Jeffrey Luo, kpt-odoo, Samuel Fritz Struble, sura-odoo, John Kirkwood (kij), utma-odoo, Sylvio Poliart (sypol), mojem, Killian Frappart, saurabh, Farah (ahmfa)
WEBSITE
WEBSITE
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 01:25:57
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - base
    - mail
    - base_setup
    - web
    - bus
    - web_tour
    - html_editor
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
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 xpath Inherits mail.mail_activity_schedule_view_form
mail_activity_view_form_popup mail.activity.form.inherit.calendar mail.activity xpath Inherits mail.mail_activity_view_form_popup
res_config_settings_view_form res.config.settings.view.form.inherit.calendar res.config.settings xpath Inherits base.res_config_settings_view_form
res_partner_kanban_view res.partner.view.kanban.calendar res.partner xpath Inherits base.res_partner_kanban_view
res_users_form_view res.users.form.calendar res.users xpath Inherits base.view_users_form
res_users_form_view_calendar_default_privacy res.users.preferences.form.inherit res.users xpath Inherits base.view_users_form_simple_modif
res_users_view_form res.users.view.form.inherit.calendar res.users notebook 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_partners_form res_partner.view.form.calendar res.partner data Inherits base.view_partner_form
Models touched (17)

New fields (7)
  • 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'
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
    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 (64)
  • 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
    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'
  • 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'
  • 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
    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' 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
  • until Date
    compute='_compute_recurrence' readonly=False
  • user_can_edit Boolean
    compute='_compute_user_can_edit'
  • user_id Many2one → res.users
    default=<expr> args: 'res.users', 'Organizer'
  • videocall_channel_id Many2one → discuss.channel
    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)
  • 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
  • read_group(self, domain, fields, groupby, offset=0, limit=None, orderby=False, lazy=True)
    @api.model
  • set_discuss_videocall_location(self)
  • unlink(self)
  • write(self, values)

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 (2)
  • delete Selection
    default='one' args: [('one', 'Delete this event'), ('next', 'Delete this and following events'), ('all', 'Delete all the events')]
  • record Many2one → calendar.event
    args: 'calendar.event', 'Calendar Event'
Public methods (1)
  • 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 (0)

No new fields.

Public methods (0)

No public methods.

New fields (1)
  • calendar_event_id Many2one → calendar.event
    ondelete='cascade' string='Calendar Meeting' args: 'calendar.event'
Public methods (2)
  • action_create_calendar_event(self)
  • unlink_w_meeting(self)

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'), ('private', 'Private'), ('confidential', 'Only internal users')]
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.

REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/17.0/calendar
VERSION
VERSION 1.1
CATEGORY
CATEGORYProductivity/Calendar
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONYes
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORS
MAINTAINERS
MAINTAINERS
COMMITTERS
COMMITTERSRaphael Collet, Odoo Translation Bot, Martin Trigaux, Thibault Delavallée, Xavier ALT, Xavier Morel, Aaron Bohy, Damien Bouvy, Yannick Tivisse, Odoo Online, Romain Derie, Jorge Pinna Puissant, Jairo Llopis, Alexandre Kühn, Aurélien Warnon, Xavier-Do, Romeo Fragomeli, Sébastien Theys, Akim Juillerat, Joseph Caburnay, Samuel Degueldre, Nasreddin Boulif (bon), Tiffany Chang (tic), Rémy Voet (ryv), Gorash, Pierre Paridans, Arnaud Joset, William Braeckman, Hubert Van de Walle (huvw), pedrambiria, Florian Damhaut, mafo-odoo, Florian Vranckx, Florian Charlier, Abdelouahab (abla), Antoine Vandevenne (anv), Renaud Thiry, niyasraphy, Thomas Lefebvre (thle), Archana Vaghasiya, Pedram (PEBR), Louis Wicket (wil), tsm-odoo, nda, Victor Piryns (pivi), Yash Vaishnav, Julien (jula), Mahamadasif Ansari, Thomas Becquevort (thbe), Pierre-Yves Dufays, Levi Siuzdak (sile), Maruan Aguerdouh (magm), Dylan Kiss (dyki), Mahdi cheikh rouhou (macr), Bruno Boi, Maitri Patel, FrancoisGe, Michael (mcm), Mayurrajsinh Rathod, Kartik Chavda, Xavier Bol (xbo), Brieuc-brd, AH-Yussef, Leonardo Pavan Rocha, Mahdi Cheikh Rouhou (macr), Andrzej(pian), Jay Savaliya, Mattis Megevand, Youssef Bashandy, lase@odoo.com, bary, Maryam Kia, jorv-odoo, Jérémy Hennecart (jeh), Julien Carion (juca), Gabriel (gdpf), Tanguy Quéguineur, ahmad(alah), Chrysanthe (chgo), Louis (wil), mano-odoo, aamo-odoo, Jonathan, Elisabeth Dickinson, Ryan Cen, sben-odoo, Ezzuldin Zaky (ezza), abdelrahmanfawzy, Gabriel de Paula Felix (gdpf), Viktors Lipskis (vili), nikj-odoo, Pierre Pulinckx (pipu), Bastien PIERRE, kpt-odoo, Samuel Fritz Struble, sura-odoo, John Kirkwood (kij), Pulinckx Pierre (PIPU), utma-odoo, Sylvio Poliart (sypol), mojem
WEBSITE
WEBSITE
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 01:02:08
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - base
    - mail
    - base_setup
    - web
    - bus
    - web_tour
    - onboarding
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
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 (17)
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 xpath Inherits mail.mail_activity_schedule_view_form
mail_activity_view_form_popup mail.activity.form.inherit.calendar mail.activity xpath Inherits mail.mail_activity_view_form_popup
res_config_settings_view_form res.config.settings.view.form.inherit.calendar res.config.settings xpath Inherits base.res_config_settings_view_form
res_partner_kanban_view res.partner.view.kanban.calendar res.partner field Inherits base.res_partner_kanban_view
res_users_view_form res.users.view.form.inherit.calendar res.users notebook Inherits base.view_users_form
view_calendar_alarm_tree calendar.alarm.tree calendar.alarm tree 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.tree calendar.event tree New
view_calendar_event_type_tree calendar.event.type calendar.event.type tree New
view_partners_form res_partner.view.form.calendar res.partner data Inherits base.view_partner_form
Models touched (19)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (7)
  • 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'
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
    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)
    @api.returns('self', <expr>)
  • 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 (64)
  • 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
    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'
  • 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'
  • 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
    default='public' help='People to whom this event will be visible.' required=True args: [('public', 'Public'), ('private', 'Private'), ('confidential', 'Only internal users')], 'Privacy'
  • recurrence_id Many2one → calendar.recurrence
    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' 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
  • until Date
    compute='_compute_recurrence' readonly=False
  • user_can_edit Boolean
    compute='_compute_user_can_edit'
  • user_id Many2one → res.users
    default=<expr> args: 'res.users', 'Organizer'
  • videocall_channel_id Many2one → discuss.channel
    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 (21)
  • 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)
  • 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_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
  • read_group(self, domain, fields, groupby, offset=0, limit=None, orderby=False, lazy=True)
    @api.model
  • set_discuss_videocall_location(self)
  • unlink(self)
  • write(self, values)

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 (2)
  • delete Selection
    default='one' args: [('one', 'Delete this event'), ('next', 'Delete this and following events'), ('all', 'Delete all the events')]
  • record Many2one → calendar.event
    args: 'calendar.event', 'Calendar Event'
Public methods (1)
  • 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 (0)

No new fields.

Public methods (0)

No public methods.

New fields (1)
  • calendar_event_id Many2one → calendar.event
    ondelete='cascade' string='Calendar Meeting' args: 'calendar.event'
Public methods (2)
  • action_create_calendar_event(self)
  • unlink_w_meeting(self)

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 (0)

No new fields.

Public methods (1)
  • action_close_calendar_onboarding(self)
    @api.model

New fields (0)

No new fields.

Public methods (1)
  • action_view_start_calendar_sync(self)
    @api.model

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 (0)

No new fields.

Public methods (2)
  • check_calendar_credentials(self)
    @api.model
  • systray_get_activities(self)
    @api.model
REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/16.0/calendar
VERSION
VERSION 1.1
CATEGORY
CATEGORYProductivity/Calendar
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONYes
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORS
MAINTAINERS
MAINTAINERS
COMMITTERS
COMMITTERSRaphael Collet, Odoo Translation Bot, Martin Trigaux, Fabien Pinckaers, Thibault Delavallée, Xavier ALT, Xavier Morel, Nicolas Lempereur, Aaron Bohy, Damien Bouvy, Yannick Tivisse, qsm-odoo, Dharmraj Jhala, Jairo Llopis, Alexandre Kühn, Julien Castiaux, Xavier-Do, Romeo Fragomeli, Victor Feyens, Sébastien Theys, Akim Juillerat, Julien Mougenot, Samuel Degueldre, std-odoo, Rémy Baranx (bar), Rémy Voet (ryv), Gorash, Arnaud Joset, William Braeckman, roen-odoo, Hubert Van de Walle (huvw), Miquel Raïch, pedrambiria, Laurent Desausoi (lade), Víctor Martínez, Florian Damhaut, Audric Onockx (auon), Florian Vranckx, Florian Charlier, Patrick Hoste, Abdelouahab (abla), Antoine Vandevenne (anv), Renaud Thiry, Julien Banken, Iván Todorovich, Thomas Lefebvre (thle), Archana Vaghasiya, Pedram (PEBR), Louis Wicket (wil), tsm-odoo, nda, Julien (jula), Mahamadasif Ansari, Thomas Becquevort (thbe), Levi Siuzdak (sile), dasa-odoo, Maruan Aguerdouh (magm), Jinane Maksoud, Sébastien Geelen (sge), Mahdi cheikh rouhou (macr), Bruno Boi, Maitri Patel, Mitul Shah, Michael (mcm), Chong Wang (cwg), Nguyễn Đại Dương, AH-Yussef, Leonardo Pavan Rocha, Mahdi Cheikh Rouhou (macr), Andrzej(pian), MAHAMADASIF ANSARI, lase@odoo.com, jorv-odoo, Jérémy Hennecart (jeh), Carlos Roca, Gabriel (gdpf), yaih-odoo, Tanguy Quéguineur, Martin Trigaux (mat), Jonathan, Majed Alhanash (malh), abdelrahmanfawzy, Gabriel de Paula Felix (gdpf), kpt-odoo, Samuel Fritz Struble, sura-odoo
WEBSITE
WEBSITE
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:40:51
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - base
    - mail
    - base_setup
    - web
    - bus
    - web_tour
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
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 (13)
XML IDNameModelTypeStatus
calendar_alarm_view_form calendar.alarm.form calendar.alarm 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_view_form_popup mail.activity.form.inherit.calendar mail.activity xpath Inherits mail.mail_activity_view_form_popup
res_partner_kanban_view res.partner.view.kanban.calendar res.partner field Inherits base.res_partner_kanban_view
res_users_view_form res.users.view.form.inherit.calendar res.users notebook Inherits base.view_users_form
view_calendar_alarm_tree calendar.alarm.tree calendar.alarm tree 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_search calendar.event.search calendar.event search New
view_calendar_event_tree calendar.event.tree calendar.event tree New
view_calendar_event_type_tree calendar.event.type calendar.event.type tree New
view_partners_form res_partner.view.form.calendar res.partner data Inherits base.view_partner_form
Models touched (15)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (7)
  • 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'
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
    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
    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' readonly=True string='Status' args: STATE_SELECTION
Public methods (7)
  • copy(self, default=None)
    @api.returns('self', <expr>)
  • 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 (54)
  • 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'
  • attendee_status Selection
    compute='_compute_attendee' string='Attendee Status' args: Attendee.STATE_SELECTION
  • 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='Repeat'
  • day Integer
    compute='_compute_recurrence' readonly=False args: 'Date of month'
  • description Html
    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'
  • 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 Every'
  • 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'
  • 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
    default='public' help='People to whom this event will be visible.' required=True args: [('public', 'Public'), ('private', 'Private'), ('confidential', 'Only internal users')], 'Privacy'
  • recurrence_id Many2one → calendar.recurrence
    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'
  • 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
  • sat Boolean
    compute='_compute_recurrence' readonly=False
  • 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=fields.Date.today help='Start date of an event, without time for full days events' 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=<expr> 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
  • thu Boolean
    compute='_compute_recurrence' readonly=False
  • tue Boolean
    compute='_compute_recurrence' readonly=False
  • until Date
    compute='_compute_recurrence' readonly=False
  • user_id Many2one → res.users
    default=<expr> args: 'res.users', 'Organizer'
  • videocall_channel_id Many2one → mail.channel
    args: 'mail.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)
  • change_attendee_status(self, status, recurrence_update_setting)
  • clear_videocall_location(self)
  • convert_online_event_desc_to_text(self, description)
    We can sync the calendar events with google calendar, iCal and Outlook, and we also pass the event description along with other data. This description needs to be in plaintext to be displayed properly in above platforms. Because online events have fixed format for the description, this method removes some specific html tags, and converts it into readable plaintext (to be used in external calendars). Note that for regular (offline) events, we simply use the standard `html2plaintext` method instead.
  • 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_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().
  • name_get(self)
    Hide private events' name for events which don't belong to the current user
  • read(self, fields=None, load='_classic_read')
    Return the events information to be shown on calendar/tree/form views. Private events will have their sensitive fields hidden by default.
  • read_group(self, domain, fields, groupby, offset=0, limit=None, orderby=False, lazy=True)
    @api.model
  • set_discuss_videocall_location(self)
  • unlink(self)
  • write(self, values)

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 required=True args: 'res.users', 'Me'
Public methods (1)
  • unlink_from_partner_id(self, partner_id)
    @api.model

New fields (5)
  • cal_client_id Char
    default=<expr> args: 'Google Client_id'
  • cal_client_secret Char
    default=<expr> args: 'Google Client_key'
  • 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'
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 (22)
  • 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
  • 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 (0)

No new fields.

Public methods (0)

No public methods.

New fields (1)
  • calendar_event_id Many2one → calendar.event
    ondelete='cascade' string='Calendar Meeting' args: 'calendar.event'
Public methods (2)
  • action_create_calendar_event(self)
  • unlink_w_meeting(self)

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 (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: - base_calendar.js : Many2ManyAttendee - calendar_model.js (calendar.CalendarModel)
  • schedule_meeting(self)

New fields (0)

No new fields.

Public methods (1)
  • systray_get_activities(self)
    @api.model
REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/15.0/calendar
VERSION
VERSION 1.1
CATEGORY
CATEGORYProductivity/Calendar
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONYes
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORS
MAINTAINERS
MAINTAINERS
COMMITTERS
COMMITTERSRaphael Collet, Odoo Translation Bot, Martin Trigaux, Thibault Delavallée, Xavier Morel, Nicolas Martinelli, Thibault Francois, Aaron Bohy, Jeremy Kersten, Barad Mahendra, Yannick Tivisse, Dharmraj Jhala, Christophe Monniez, Alexandre Kühn, Julien Castiaux, Aurélien Warnon, Xavier-Do, Sébastien Theys, Akim Juillerat, Nasreddin (bon), Julien Mougenot, Anh Thao Pham (pta), Achraf (abz), Adrien Widart, Ivan Yelizariev, Jérémy Hennecart, Kamesh Patel, Nicolas Galler, Tiffany Chang (tic), Rémy Voet (ryv), Arnaud Joset, nounoubensebia, Kevin Baptiste, roen-odoo, Hubert Van de Walle (huvw), qmo-odoo, pedrambiria, Laurent Desausoi (lade), sergio-teruel, Víctor Martínez, Florian Damhaut, Audric Onockx (auon), Florian Vranckx, Abdelouahab (abla), Nicolas Bayet, Michael Mattiello (mcm), dht-odoo, Renaud Thiry, Thomas Lefebvre (thle), Archana Vaghasiya, Pedram (PEBR), nda, Julien (jula), Pierre-Yves Dufays, Qiuyu (QHO), Munaf Khan, dasa-odoo, Jinane Maksoud, Sébastien Geelen (sge), Mahdi cheikh rouhou (macr), Maitri Patel, Leonardo Pavan Rocha, Mahdi Cheikh Rouhou (macr), Zelong Lin, Damien (abd), MAHAMADASIF ANSARI, lase@odoo.com, Jérémy Hennecart (jeh), Carlos Roca, Gabriel (gdpf), yaih-odoo
WEBSITE
WEBSITE
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:25:28
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - base
    - mail
    - base_setup
    - web
    - bus
    - web_tour
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
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 (12)
XML IDNameModelTypeStatus
calendar_alarm_view_form calendar.alarm.form calendar.alarm form New
invitation_page_anonymous Calendar Invitation Page for anonymous users ir.ui.view qweb New
mail_activity_view_form_popup mail.activity.form.inherit.calendar mail.activity xpath Inherits mail.mail_activity_view_form_popup
res_partner_kanban_view res.partner.view.kanban.calendar res.partner field Inherits base.res_partner_kanban_view
res_users_view_form res.users.view.form.inherit.calendar res.users notebook Inherits base.view_users_form
view_calendar_alarm_tree calendar.alarm.tree calendar.alarm tree 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_search calendar.event.search calendar.event search New
view_calendar_event_tree calendar.event.tree calendar.event tree New
view_calendar_event_type_tree calendar.event.type calendar.event.type tree New
view_partners_form res_partner.view.form.calendar res.partner data Inherits base.view_partner_form
Models touched (13)

New fields (7)
  • 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' help='Duration in 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'
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
    help='Email of Invited Person' related='partner_id.email' args: 'Email'
  • event_id Many2one → calendar.event
    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
    readonly=True required=True args: 'res.partner', 'Attendee'
  • phone Char
    help='Phone number of Invited Person' related='partner_id.phone' args: 'Phone'
  • recurrence_id Many2one → calendar.recurrence
    related='event_id.recurrence_id' args: 'calendar.recurrence'
  • state Selection
    default='needsAction' help="Status of the attendee's participation" readonly=True string='Status' args: STATE_SELECTION
Public methods (6)
  • copy(self, default=None)
    @api.returns('self', <expr>)
  • 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)

New fields (50)
  • 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'
  • attendee_status Selection
    compute='_compute_attendee' string='Attendee Status' args: Attendee.STATE_SELECTION
  • byday Selection
    compute='_compute_recurrence' readonly=False 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='Repeat'
  • day Integer
    compute='_compute_recurrence' readonly=False args: 'Date of month'
  • description Html
    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'
  • 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 Every'
  • 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
    help='Location of Event' 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'
  • 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
    default='public' help='People to whom this event will be visible.' required=True args: [('public', 'Public'), ('private', 'Private'), ('confidential', 'Only internal users')], 'Privacy'
  • recurrence_id Many2one → calendar.recurrence
    index=True 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 Integer
    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'
  • 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
  • sat Boolean
    compute='_compute_recurrence' readonly=False
  • 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=fields.Date.today help='Start date of an event, without time for full days events' 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=<expr> 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
  • thu Boolean
    compute='_compute_recurrence' readonly=False
  • tue Boolean
    compute='_compute_recurrence' readonly=False
  • until Date
    compute='_compute_recurrence' readonly=False
  • user_id Many2one → res.users
    default=<expr> args: 'res.users', 'Organizer'
  • videocall_location Char
    args: 'Meeting URL'
  • wed Boolean
    compute='_compute_recurrence' readonly=False
  • weekday Selection
    compute='_compute_recurrence' readonly=False args: WEEKDAY_SELECTION
Public methods (18)
  • action_join_meeting(self, partner_id)
    Method used when an existing user wants to join
  • 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)
  • change_attendee_status(self, status, recurrence_update_setting)
  • convert_online_event_desc_to_text(self, description)
    We can sync the calendar events with google calendar, iCal and Outlook, and we also pass the event description along with other data. This description needs to be in plaintext to be displayed properly in above platforms. Because online events have fixed format for the description, this method removes some specific html tags, and converts it into readable plaintext (to be used in external calendars). Note that for regular (offline) events, we simply use the standard `html2plaintext` method instead.
  • 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_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().
  • name_get(self)
    Hide private events' name for events which don't belong to the current user
  • read(self, fields)
    Return the events information to be shown on calendar/tree/form views. Private events will have their sensitive fields hidden by default.
  • read_group(self, domain, fields, groupby, offset=0, limit=None, orderby=False, lazy=True)
    @api.model
  • unlink(self)
  • write(self, values)

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 help='This field is used to know if the partner is checked in the filter of the calendar view for the user_id.' args: 'Checked'
  • partner_id Many2one → res.partner
    required=True args: 'res.partner', 'Employee'
  • user_id Many2one → res.users
    default=<expr> required=True args: 'res.users', 'Me'
Public methods (1)
  • unlink_from_partner_id(self, partner_id)
    @api.model

New fields (22)
  • 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
  • tue Boolean
  • until Date
    args: 'Repeat Until'
  • wed Boolean
  • weekday Selection
    string='Weekday' args: WEEKDAY_SELECTION
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
    ondelete='cascade' string='Calendar Meeting' args: 'calendar.event'
Public methods (2)
  • action_create_calendar_event(self)
  • unlink_w_meeting(self)

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 (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: - base_calendar.js : Many2ManyAttendee - calendar_model.js (calendar.CalendarModel)
  • schedule_meeting(self)

New fields (0)

No new fields.

Public methods (1)
  • systray_get_activities(self)
    @api.model
REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/14.0/calendar
VERSION
VERSION 1.0
CATEGORY
CATEGORYProductivity/Calendar
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONYes
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORS
MAINTAINERS
MAINTAINERS
COMMITTERS
COMMITTERSOdoo Translation Bot, Martin Trigaux, Fabien Pinckaers, Olivier Dony, Thibault Delavallée, Christophe Simonis, Xavier Morel, Nicolas Martinelli, Nicolas Lempereur, Thibault Francois, Aaron Bohy, Barad Mahendra, Yannick Tivisse, Dharmraj Jhala, SEINLET Nicolas, Christophe Monniez, Jorge Pinna Puissant, Alexandre Kühn, Julien Castiaux, Xavier-Do, jvm-odoo, jerome hanke (jhk), Andrea Grazioso (agr-odoo), Sébastien Theys, Nasreddin (bon), Julien Mougenot, fw-bot, Anh Thao Pham (pta), Rémy Baranx (bar), Achraf (abz), Lucas Lefèvre, Adrien Widart, Ivan Yelizariev, Hubert (huvw), Jérémy Hennecart, Prakash Prajapati, Kamesh Patel, Nicolas Galler, Nathan Marotte (nama), Pierre Paridans, Djamel (otd), Yenthe666, jbm-odoo, Aurélien (avd), Arnaud Joset, root, Kevin Baptiste, Hubert Van de Walle (huvw), pedrambiria, Florian Damhaut, mafo-odoo, Audric Onockx (auon), Florian Vranckx, Thomas Lefebvre (thle), Chong Wang (cwg)
WEBSITE
WEBSITE
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:14:29
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - base
    - mail
    - base_setup
    - web
    - bus
    - web_tour
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
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 (11)
XML IDNameModelTypeStatus
assets_backend calendar assets ir.ui.view qweb Inherits web.assets_backend
calendar_alarm_view_form calendar.alarm.form calendar.alarm form New
invitation_page_anonymous Calendar Invitation Page for anonymous users ir.ui.view qweb New
mail_activity_view_form_popup mail.activity.form.inherit.calendar mail.activity xpath Inherits mail.mail_activity_view_form_popup
qunit_suite qunit_suite ir.ui.view qweb Inherits web.qunit_suite_tests
view_calendar_alarm_tree calendar.alarm.tree calendar.alarm tree 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_search calendar.event.search calendar.event search New
view_calendar_event_tree calendar.event.tree calendar.event tree New
view_calendar_event_type_tree calendar.event.type calendar.event.type tree New
Models touched (12)

New fields (5)
  • alarm_type Selection
    default='email' required=True string='Type' args: [('notification', 'Notification'), ('email', 'Email')]
  • duration Integer
    default=1 required=True args: 'Remind Before'
  • duration_minutes Integer
    compute='_compute_duration_minutes' help='Duration in minutes' search='_search_duration_minutes' store=True args: 'Duration in minutes'
  • interval Selection
    default='hours' required=True args: list(_interval_selection.items()), 'Unit'
  • name Char
    required=True translate=True args: 'Name'
Public methods (3)
  • create(self, values)
    @api.model
  • unlink(self)
  • write(self, values)

New fields (0)

No new fields.

Public methods (5)
  • 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_mail_reminder(self, alert)
  • do_notif_reminder(self, alert)
  • get_next_mail(self)
    @api.model
  • get_next_notif(self)
    @api.model

New fields (8)
  • access_token Char
    default=_default_access_token args: 'Invitation Token'
  • availability Selection
    readonly=True args: [('free', 'Free'), ('busy', 'Busy')], 'Free/Busy'
  • common_name Char
    compute='_compute_common_name' store=True args: 'Common name'
  • email Char
    help='Email of Invited Person' related='partner_id.email' args: 'Email'
  • event_id Many2one → calendar.event
    ondelete='cascade' required=True args: 'calendar.event', 'Meeting linked'
  • partner_id Many2one → res.partner
    readonly=True required=True args: 'res.partner', 'Contact'
  • recurrence_id Many2one → calendar.recurrence
    related='event_id.recurrence_id' args: 'calendar.recurrence'
  • state Selection
    default='needsAction' help="Status of the attendee's participation" readonly=True string='Status' args: STATE_SELECTION
Public methods (6)
  • copy(self, default=None)
    @api.returns('self', <expr>)
  • 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)

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

New fields (48)
  • 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.' args: 'Active'
  • activity_ids One2many → mail.activity
    string='Activities' args: 'mail.activity', 'calendar_event_id'
  • alarm_ids Many2many → calendar.alarm
    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'
  • attendee_status Selection
    compute='_compute_attendee' string='Attendee Status' args: Attendee.STATE_SELECTION
  • byday Selection
    compute='_compute_recurrence' readonly=False 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='Repeat'
  • day Integer
    compute='_compute_recurrence' readonly=False args: 'Date of month'
  • description Text
    args: 'Description'
  • display_time Char
    compute='_compute_display_time' args: 'Event Time'
  • duration Float
    compute='_compute_duration' readonly=False store=True args: 'Duration'
  • 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
  • fr Boolean
    compute='_compute_recurrence' readonly=False args: 'Fri'
  • interval Integer
    compute='_compute_recurrence' help='Repeat every (Days/Week/Month/Year)' readonly=False string='Repeat Every'
  • is_highlighted Boolean
    compute='_compute_is_highlighted' string='Is the Event Highlighted'
  • location Char
    help='Location of Event' tracking=True args: 'Location'
  • message_ids One2many
    auto_join=False
  • mo Boolean
    compute='_compute_recurrence' readonly=False args: 'Mon'
  • month_by Selection
    compute='_compute_recurrence' readonly=False string='Option' args: MONTH_BY_SELECTION
  • name Char
    required=True args: 'Meeting Subject'
  • partner_id Many2one → res.partner
    readonly=True related='user_id.partner_id' string='Responsible Contact' args: 'res.partner'
  • partner_ids Many2many → res.partner
    default=_default_partners string='Attendees' args: 'res.partner', 'calendar_event_res_partner_rel'
  • privacy Selection
    default='public' required=True args: [('public', 'Everyone'), ('private', 'Only me'), ('confidential', 'Only internal users')], 'Privacy'
  • recurrence_id Many2one → calendar.recurrence
    index=True 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
    help='Recurrent Event' args: 'Recurrent'
  • res_id Integer
    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'
  • 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
  • sa Boolean
    compute='_compute_recurrence' readonly=False args: 'Sat'
  • show_as Selection
    default='busy' required=True args: [('free', 'Free'), ('busy', 'Busy')], 'Show Time as'
  • start Datetime
    default=fields.Date.today help='Start date of an event, without time for full days events' 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=<expr> 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'
  • su Boolean
    compute='_compute_recurrence' readonly=False args: 'Sun'
  • th Boolean
    compute='_compute_recurrence' readonly=False args: 'Thu'
  • tu Boolean
    compute='_compute_recurrence' readonly=False args: 'Tue'
  • until Date
    compute='_compute_recurrence' readonly=False
  • user_id Many2one → res.users
    default=<expr> args: 'res.users', 'Responsible'
  • we Boolean
    compute='_compute_recurrence' readonly=False args: 'Wed'
  • weekday Selection
    compute='_compute_recurrence' readonly=False args: WEEKDAY_SELECTION
Public methods (11)
  • action_open_calendar_event(self)
  • action_sendmail(self)
  • change_attendee_status(self, status)
  • create(self, vals_list)
    @api.model_create_multi
  • default_get(self, fields)
    @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_interval(self, interval, tz=None)
    Format and localize some dates to be used in email templates :param string interval: Among 'day', 'month', 'dayname' and 'time' indicating the desired formatting :param string tz: Timezone indicator (optional) :return unicode: Formatted date or time (as unicode string, to prevent jinja2 crash)
  • name_get(self)
    Hide private events' name for events which don't belong to the current user
  • read_group(self, domain, fields, groupby, offset=0, limit=None, orderby=False, lazy=True)
    @api.model
  • unlink(self)
  • write(self, values)

New fields (1)
  • name Char
    required=True args: 'Name'
Public methods (0)

No public methods.

New fields (22)
  • 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
  • fr Boolean
  • interval Integer
    default=1
  • mo 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
  • sa Boolean
  • su Boolean
  • th Boolean
  • tu Boolean
  • until Date
    args: 'Repeat Until'
  • we Boolean
  • weekday Selection
    string='Weekday' args: WEEKDAY_SELECTION
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
    ondelete='cascade' string='Calendar Meeting' args: 'calendar.event'
Public methods (2)
  • action_create_calendar_event(self)
  • unlink_w_meeting(self)

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

No public methods.

New fields (1)
  • calendar_last_notif_ack Datetime
    default=fields.Datetime.now args: 'Last notification marked as read from base Calendar'
Public methods (1)
  • get_attendee_detail(self, meeting_id)
    Return a list of tuple (id, name, status) Used by base_calendar.js : Many2ManyAttendee

New fields (0)

No new fields.

Public methods (1)
  • systray_get_activities(self)
    @api.model
REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/13.0/calendar
VERSION
VERSION 1.0
CATEGORY
CATEGORYTools
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONYes
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORS
MAINTAINERS
MAINTAINERS
COMMITTERS
COMMITTERSRaphael Collet, Odoo Translation Bot, Martin Trigaux, Thibault Delavallée, Denis Ledoux, Christophe Simonis, Xavier Morel, Mohammed Shekha, Nicolas Martinelli, Nicolas Lempereur, Aaron Bohy, Jeremy Kersten, GitHub, Damien Bouvy, Yannick Tivisse, qsm-odoo, Martin Geubelle, Odoo Online, Jigar Patel, jem-odoo, Jorge Pinna Puissant, Nans Lefebvre, Alexandre Kühn, Adrian Torres, Xavier-Do, jvm-odoo, jerome hanke (jhk), Andrea Grazioso (agr-odoo), Sébastien Theys, fw-bot, Anh Thao Pham (pta), Adrien Widart, Ivan Yelizariev, Prakash Prajapati, Kamesh Patel, Nicolas Galler, Swapnesh Shah, nie, IEL, Thanh Dodeur, PermanAtayev, Romain Estievenart, Florian Damhaut
WEBSITE
WEBSITE
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 00:06:43
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - base
    - mail
    - base_setup
    - web
    - bus
    - web_tour
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
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 (11)
XML IDNameModelTypeStatus
assets_backend calendar assets ir.ui.view qweb Inherits web.assets_backend
calendar_alarm_view_form calendar.alarm.form calendar.alarm form New
invitation_page_anonymous Calendar Invitation Page for anonymous users ir.ui.view qweb New
mail_activity_view_form_popup mail.activity.form.inherit.calendar mail.activity xpath Inherits mail.mail_activity_view_form_popup
qunit_suite qunit_suite ir.ui.view qweb Inherits web.qunit_suite
view_calendar_alarm_tree calendar.alarm.tree calendar.alarm tree 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_search calendar.event.search calendar.event search New
view_calendar_event_tree calendar.event.tree calendar.event tree New
view_calendar_event_type_tree calendar.event.type calendar.event.type tree New
Models touched (14)

New fields (5)
  • alarm_type Selection
    default='email' required=True string='Type' args: [('notification', 'Notification'), ('email', 'Email')]
  • duration Integer
    default=1 required=True args: 'Remind Before'
  • duration_minutes Integer
    compute='_compute_duration_minutes' help='Duration in minutes' store=True args: 'Duration in minutes'
  • interval Selection
    default='hours' required=True args: list(_interval_selection.items()), 'Unit'
  • name Char
    required=True translate=True args: 'Name'
Public methods (3)
  • create(self, values)
    @api.model
  • unlink(self)
  • write(self, values)

New fields (0)

No new fields.

Public methods (5)
  • 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_mail_reminder(self, alert)
  • do_notif_reminder(self, alert)
  • get_next_mail(self)
    @api.model
  • get_next_notif(self)
    @api.model

New fields (7)
  • access_token Char
    default=_default_access_token args: 'Invitation Token'
  • availability Selection
    readonly=True args: [('free', 'Free'), ('busy', 'Busy')], 'Free/Busy'
  • common_name Char
    compute='_compute_common_name' store=True args: 'Common name'
  • email Char
    help='Email of Invited Person' args: 'Email'
  • event_id Many2one → calendar.event
    ondelete='cascade' args: 'calendar.event', 'Meeting linked'
  • partner_id Many2one → res.partner
    readonly=True args: 'res.partner', 'Contact'
  • state Selection
    default='needsAction' help="Status of the attendee's participation" readonly=True string='Status' args: STATE_SELECTION
Public methods (5)
  • copy(self, default=None)
    @api.returns('self', <expr>)
  • 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.

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

New fields (52)
  • 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.' args: 'Active'
  • activity_ids One2many → mail.activity
    string='Activities' args: 'mail.activity', 'calendar_event_id'
  • alarm_ids Many2many → calendar.alarm
    copy=False ondelete='restrict' string='Reminders' args: 'calendar.alarm', 'calendar_alarm_calendar_event_rel'
  • allday Boolean
    default=False states={'done': [('readonly', True)]} args: 'All Day'
  • attendee_ids One2many → calendar.attendee
    ondelete='cascade' args: 'calendar.attendee', 'event_id', 'Participant'
  • attendee_status Selection
    compute='_compute_attendee' string='Attendee Status' args: Attendee.STATE_SELECTION
  • byday Selection
    string='By day' args: [('1', 'First'), ('2', 'Second'), ('3', 'Third'), ('4', 'Fourth'), ('5', 'Fifth'), ('-1', 'Last')]
  • categ_ids Many2many → calendar.event.type
    args: 'calendar.event.type', 'meeting_category_rel', 'event_id', 'type_id', 'Tags'
  • count Integer
    default=1 help='Repeat x times' string='Repeat'
  • day Integer
    default=1 args: 'Date of month'
  • description Text
    states={'done': [('readonly', True)]} args: 'Description'
  • display_start Char
    compute='_compute_display_start' store=True args: 'Date'
  • display_time Char
    compute='_compute_display_time' args: 'Event Time'
  • duration Float
    states={'done': [('readonly', True)]} args: 'Duration'
  • end_type Selection
    default='count' string='Recurrence Termination' args: [('count', 'Number of repetitions'), ('end_date', 'End date')]
  • event_tz Selection
    default=<expr> string='Timezone' args: '_event_tz_get'
  • final_date Date
    args: 'Repeat Until'
  • fr Boolean
    args: 'Fri'
  • interval Integer
    default=1 help='Repeat every (Days/Week/Month/Year)' string='Repeat Every'
  • is_attendee Boolean
    compute='_compute_attendee' args: 'Attendee'
  • is_highlighted Boolean
    compute='_compute_is_highlighted' string='Is the Event Highlighted'
  • location Char
    help='Location of Event' states={'done': [('readonly', True)]} tracking=True args: 'Location'
  • message_ids One2many
    auto_join=False
  • mo Boolean
    args: 'Mon'
  • month_by Selection
    default='date' string='Option' args: [('date', 'Date of month'), ('day', 'Day of month')]
  • name Char
    required=True states={'done': [('readonly', True)]} args: 'Meeting Subject'
  • partner_id Many2one → res.partner
    readonly=True related='user_id.partner_id' string='Responsible' args: 'res.partner'
  • partner_ids Many2many → res.partner
    default=_default_partners states={'done': [('readonly', True)]} string='Attendees' args: 'res.partner', 'calendar_event_res_partner_rel'
  • privacy Selection
    default='public' states={'done': [('readonly', True)]} args: [('public', 'Everyone'), ('private', 'Only me'), ('confidential', 'Only internal users')], 'Privacy'
  • recurrency Boolean
    help='Recurrent Meeting' args: 'Recurrent'
  • recurrent_id Integer
    args: 'Recurrent ID'
  • recurrent_id_date Datetime
    args: 'Recurrent ID date'
  • res_id Integer
    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'
  • rrule Char
    compute='_compute_rrule' inverse='_inverse_rrule' store=True args: 'Recurrent Rule'
  • rrule_type Selection
    help='Let the event automatically repeat at that interval' states={'done': [('readonly', True)]} string='Recurrence' args: [('daily', 'Days'), ('weekly', 'Weeks'), ('monthly', 'Months'), ('yearly', 'Years')]
  • sa Boolean
    args: 'Sat'
  • show_as Selection
    default='busy' states={'done': [('readonly', True)]} args: [('free', 'Free'), ('busy', 'Busy')], 'Show Time as'
  • start Datetime
    help='Start date of an event, without time for full days events' required=True args: 'Start'
  • start_date Date
    compute='_compute_dates' inverse='_inverse_dates' states={'done': [('readonly', True)]} store=True tracking=True args: 'Start Date'
  • start_datetime Datetime
    compute='_compute_dates' inverse='_inverse_dates' states={'done': [('readonly', True)]} store=True tracking=True args: 'Start DateTime'
  • state Selection
    default='draft' readonly=True string='Status' tracking=True args: [('draft', 'Unconfirmed'), ('open', 'Confirmed')]
  • stop Datetime
    help='Stop date of an event, without time for full days events' required=True args: 'Stop'
  • stop_date Date
    compute='_compute_dates' inverse='_inverse_dates' states={'done': [('readonly', True)]} store=True tracking=True args: 'End Date'
  • stop_datetime Datetime
    compute='_compute_dates' inverse='_inverse_dates' states={'done': [('readonly', True)]} store=True tracking=True args: 'End Datetime'
  • su Boolean
    args: 'Sun'
  • th Boolean
    args: 'Thu'
  • tu Boolean
    args: 'Tue'
  • user_id Many2one → res.users
    default=<expr> states={'done': [('readonly', True)]} args: 'res.users', 'Owner'
  • we Boolean
    args: 'Wed'
  • week_list Selection
    string='Weekday' args: [('MO', 'Monday'), ('TU', 'Tuesday'), ('WE', 'Wednesday'), ('TH', 'Thursday'), ('FR', 'Friday'), ('SA', 'Saturday'), ('SU', 'Sunday')]
Public methods (23)
  • action_detach_recurring_event(self)
  • action_open_calendar_event(self)
  • action_sendmail(self)
  • change_attendee_status(self, status)
  • copy(self, default=None)
    @api.returns('self', <expr>)
  • create(self, vals_list)
    @api.model_create_multi
  • create_attendees(self)
  • default_get(self, fields)
    @api.model
  • detach_recurring_event(self, values=None)
    Detach a virtual recurring event by duplicating the original and change reccurent values :param values : dict of value to override on the detached event
  • export_data(self, fields_to_export)
    Override to convert virtual ids to ids
  • 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_interval(self, interval, tz=None)
    Format and localize some dates to be used in email templates :param string interval: Among 'day', 'month', 'dayname' and 'time' indicating the desired formatting :param string tz: Timezone indicator (optional) :return unicode: Formatted date or time (as unicode string, to prevent jinja2 crash)
  • get_metadata(self)
  • get_recurrent_ids(self, domain, order=None)
    Gives virtual event ids for recurring events. This method gives ids of dates that comes between start date and end date of calendar views :param order: The fields (comma separated, format "FIELD {DESC|ASC}") on which the events should be sorted
  • get_search_fields(self, order_fields, r_date=None)
  • message_post(self, **kwargs)
    @api.returns('mail.message', <expr>)
  • message_subscribe(self, partner_ids=None, channel_ids=None, subtype_ids=None)
  • message_unsubscribe(self, partner_ids=None, channel_ids=None)
  • name_get(self)
    Hide private events' name for events which don't belong to the current user
  • read(self, fields=None, load='_classic_read')
  • read_group(self, domain, fields, groupby, offset=0, limit=None, orderby=False, lazy=True)
    @api.model
  • unlink(self, can_be_deleted=True)
  • write(self, values)

New fields (1)
  • name Char
    required=True args: 'Name'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (1)
  • write(self, vals)
    When posting an attachment (new or not), convert the virtual ids in real ids.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (1)
  • calendar_event_id Many2one → calendar.event
    ondelete='cascade' string='Calendar Meeting' args: 'calendar.event'
Public methods (2)
  • action_create_calendar_event(self)
  • unlink_w_meeting(self)

New fields (1)
  • category Selection
    selection_add=[('meeting', 'Meeting')]
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)
  • default_get(self, fields)
    @api.model
    In case someone clicked on 'invite others' wizard in the followers widget, transform virtual ids in real ids

New fields (1)
  • calendar_last_notif_ack Datetime
    default=fields.Datetime.now args: 'Last notification marked as read from base Calendar'
Public methods (1)
  • get_attendee_detail(self, meeting_id)
    Return a list of tuple (id, name, status) Used by base_calendar.js : Many2ManyAttendee

New fields (0)

No new fields.

Public methods (1)
  • systray_get_activities(self)
    @api.model
REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/12.0/calendar
VERSION
VERSION 1.0
CATEGORY
CATEGORYExtra Tools
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONYes
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORS
MAINTAINERS
MAINTAINERS
COMMITTERS
COMMITTERSRaphael Collet, Odoo Translation Bot, Christophe Matthieu, Martin Trigaux, Fabien Pinckaers, Thibault Delavallée, Denis Ledoux, Christophe Simonis, Xavier Morel, Nicolas Martinelli, Nicolas Lempereur, qdp-odoo, Géry Debongnie, Aaron Bohy, GitHub, Lucas Perais (lpe), Yannick Tivisse, Alexandre Kühn, qsm-odoo, jem-odoo, RomainLibert, Jorge Pinna Puissant, Nans Lefebvre, Alexandre Kühn, Adrian Torres, XavierDo, Julien Castiaux, Xavier-Do, jvm-odoo, jerome hanke (jhk), Andrea Grazioso (agr-odoo), Anh Thao Pham (pta), Kinjal Mehta, David Beguin, Kamesh Patel, Nicolas Galler, IEL, PermanAtayev
WEBSITE
WEBSITE
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-05 23:57:01
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - base
    - mail
    - base_setup
    - web
    - bus
    - web_tour
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
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 (13)
XML IDNameModelTypeStatus
assets_backend calendar assets ir.ui.view qweb Inherits web.assets_backend
calendar_alarm_view_form calendar.alarm.form calendar.alarm form New
invitation_page_anonymous Calendar Invitation Page for anonymous users ir.ui.view qweb New
mail_activity_type_view_form mail.activity.type.form.inherit.calendar mail.activity.type xpath Inherits mail.mail_activity_type_view_form
mail_activity_view_form_popup mail.activity.form.inherit.calendar mail.activity xpath Inherits mail.mail_activity_view_form_popup
qunit_suite qunit_suite ir.ui.view qweb Inherits web.qunit_suite
view_calendar_alarm_tree calendar.alarm.tree calendar.alarm tree 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_popup calendar.event.form calendar.event form New
view_calendar_event_search calendar.event.search calendar.event search New
view_calendar_event_tree calendar.event.tree calendar.event tree New
view_calendar_event_type_tree calendar.event.type calendar.event.type tree New
Models touched (14)

New fields (5)
  • duration Integer
    default=1 required=True args: 'Remind Before'
  • duration_minutes Integer
    compute='_compute_duration_minutes' help='Duration in minutes' store=True args: 'Duration in minutes'
  • interval Selection
    default='hours' required=True args: list(_interval_selection.items()), 'Unit'
  • name Char
    required=True translate=True args: 'Name'
  • type Selection
    default='email' required=True args: [('notification', 'Notification'), ('email', 'Email')], 'Type'
Public methods (3)
  • create(self, values)
    @api.model
  • unlink(self)
    @api.multi
  • write(self, values)
    @api.multi

New fields (0)

No new fields.

Public methods (7)
  • 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_mail_reminder(self, alert)
  • do_notif_reminder(self, alert)
  • get_next_mail(self)
    @api.model
  • get_next_notif(self)
    @api.model
  • get_next_potential_limit_alarm(self, alarm_type, seconds=None, partner_id=None)
  • notify_next_alarm(self, partner_ids)
    Sends through the bus the next alarm of given partners

New fields (7)
  • access_token Char
    default=_default_access_token args: 'Invitation Token'
  • availability Selection
    readonly='True' args: [('free', 'Free'), ('busy', 'Busy')], 'Free/Busy'
  • common_name Char
    compute='_compute_common_name' store=True args: 'Common name'
  • email Char
    help='Email of Invited Person' args: 'Email'
  • event_id Many2one → calendar.event
    ondelete='cascade' args: 'calendar.event', 'Meeting linked'
  • partner_id Many2one → res.partner
    readonly='True' args: 'res.partner', 'Contact'
  • state Selection
    default='needsAction' help="Status of the attendee's participation" readonly=True string='Status' args: STATE_SELECTION
Public methods (5)
  • copy(self, default=None)
    @api.multi@api.returns('self', <expr>)
  • create(self, vals_list)
    @api.model_create_multi
  • do_accept(self)
    @api.multi
    Marks event invitation as Accepted.
  • do_decline(self)
    @api.multi
    Marks event invitation as Declined.
  • do_tentative(self)
    @api.multi
    Makes event invitation as Tentative.

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

New fields (51)
  • 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.' args: 'Active'
  • activity_ids One2many → mail.activity
    string='Activities' args: 'mail.activity', 'calendar_event_id'
  • alarm_ids Many2many → calendar.alarm
    copy=False ondelete='restrict' string='Reminders' args: 'calendar.alarm', 'calendar_alarm_calendar_event_rel'
  • allday Boolean
    default=False states={'done': [('readonly', True)]} args: 'All Day'
  • attendee_ids One2many → calendar.attendee
    ondelete='cascade' args: 'calendar.attendee', 'event_id', 'Participant'
  • attendee_status Selection
    compute='_compute_attendee' string='Attendee Status' args: Attendee.STATE_SELECTION
  • byday Selection
    string='By day' args: [('1', 'First'), ('2', 'Second'), ('3', 'Third'), ('4', 'Fourth'), ('5', 'Fifth'), ('-1', 'Last')]
  • categ_ids Many2many → calendar.event.type
    args: 'calendar.event.type', 'meeting_category_rel', 'event_id', 'type_id', 'Tags'
  • count Integer
    default=1 help='Repeat x times' string='Repeat'
  • day Integer
    default=1 args: 'Date of month'
  • description Text
    states={'done': [('readonly', True)]} args: 'Description'
  • display_start Char
    compute='_compute_display_start' store=True args: 'Date'
  • display_time Char
    compute='_compute_display_time' args: 'Event Time'
  • duration Float
    states={'done': [('readonly', True)]} args: 'Duration'
  • end_type Selection
    default='count' string='Recurrence Termination' args: [('count', 'Number of repetitions'), ('end_date', 'End date')]
  • final_date Date
    args: 'Repeat Until'
  • fr Boolean
    args: 'Fri'
  • interval Integer
    default=1 help='Repeat every (Days/Week/Month/Year)' string='Repeat Every'
  • is_attendee Boolean
    compute='_compute_attendee' args: 'Attendee'
  • is_highlighted Boolean
    compute='_compute_is_highlighted' string='Is the Event Highlighted'
  • location Char
    help='Location of Event' states={'done': [('readonly', True)]} track_visibility='onchange' args: 'Location'
  • message_ids One2many
    auto_join=False
  • mo Boolean
    args: 'Mon'
  • month_by Selection
    default='date' oldname='select1' string='Option' args: [('date', 'Date of month'), ('day', 'Day of month')]
  • name Char
    required=True states={'done': [('readonly', True)]} args: 'Meeting Subject'
  • partner_id Many2one → res.partner
    readonly=True related='user_id.partner_id' string='Responsible' args: 'res.partner'
  • partner_ids Many2many → res.partner
    default=_default_partners states={'done': [('readonly', True)]} string='Attendees' args: 'res.partner', 'calendar_event_res_partner_rel'
  • privacy Selection
    default='public' oldname='class' states={'done': [('readonly', True)]} args: [('public', 'Everyone'), ('private', 'Only me'), ('confidential', 'Only internal users')], 'Privacy'
  • recurrency Boolean
    help='Recurrent Meeting' args: 'Recurrent'
  • recurrent_id Integer
    args: 'Recurrent ID'
  • recurrent_id_date Datetime
    args: 'Recurrent ID date'
  • res_id Integer
    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'
  • rrule Char
    compute='_compute_rrule' inverse='_inverse_rrule' store=True args: 'Recurrent Rule'
  • rrule_type Selection
    help='Let the event automatically repeat at that interval' states={'done': [('readonly', True)]} string='Recurrence' args: [('daily', 'Day(s)'), ('weekly', 'Week(s)'), ('monthly', 'Month(s)'), ('yearly', 'Year(s)')]
  • sa Boolean
    args: 'Sat'
  • show_as Selection
    default='busy' states={'done': [('readonly', True)]} args: [('free', 'Free'), ('busy', 'Busy')], 'Show Time as'
  • start Datetime
    help='Start date of an event, without time for full days events' required=True args: 'Start'
  • start_date Date
    compute='_compute_dates' inverse='_inverse_dates' states={'done': [('readonly', True)]} store=True track_visibility='onchange' args: 'Start Date'
  • start_datetime Datetime
    compute='_compute_dates' inverse='_inverse_dates' states={'done': [('readonly', True)]} store=True track_visibility='onchange' args: 'Start DateTime'
  • state Selection
    default='draft' readonly=True string='Status' track_visibility='onchange' args: [('draft', 'Unconfirmed'), ('open', 'Confirmed')]
  • stop Datetime
    help='Stop date of an event, without time for full days events' required=True args: 'Stop'
  • stop_date Date
    compute='_compute_dates' inverse='_inverse_dates' states={'done': [('readonly', True)]} store=True track_visibility='onchange' args: 'End Date'
  • stop_datetime Datetime
    compute='_compute_dates' inverse='_inverse_dates' states={'done': [('readonly', True)]} store=True track_visibility='onchange' args: 'End Datetime'
  • su Boolean
    args: 'Sun'
  • th Boolean
    args: 'Thu'
  • tu Boolean
    args: 'Tue'
  • user_id Many2one → res.users
    default=<expr> states={'done': [('readonly', True)]} args: 'res.users', 'Owner'
  • we Boolean
    args: 'Wed'
  • week_list Selection
    string='Weekday' args: [('MO', 'Monday'), ('TU', 'Tuesday'), ('WE', 'Wednesday'), ('TH', 'Thursday'), ('FR', 'Friday'), ('SA', 'Saturday'), ('SU', 'Sunday')]
Public methods (21)
  • action_detach_recurring_event(self)
    @api.multi
  • action_open_calendar_event(self)
    @api.multi
  • action_sendmail(self)
    @api.multi
  • copy(self, default=None)
    @api.multi@api.returns('self', <expr>)
  • create(self, values)
    @api.model
  • create_attendees(self)
    @api.multi
  • default_get(self, fields)
    @api.model
  • detach_recurring_event(self, values=None)
    @api.multi
    Detach a virtual recurring event by duplicating the original and change reccurent values :param values : dict of value to override on the detached event
  • export_data(self, fields_to_export, raw_data=False)
    @api.multi
    Override to convert virtual ids to ids
  • get_display_time_tz(self, tz=False)
    @api.multi
    get the display_time of the meeting, forcing the timezone. This method is called from email template, to not use sudo().
  • get_interval(self, interval, tz=None)
    @api.multi
    Format and localize some dates to be used in email templates :param string interval: Among 'day', 'month', 'dayname' and 'time' indicating the desired formatting :param string tz: Timezone indicator (optional) :return unicode: Formatted date or time (as unicode string, to prevent jinja2 crash)
  • get_metadata(self)
    @api.multi
  • get_recurrent_ids(self, domain, order=None)
    @api.multi
    Gives virtual event ids for recurring events. This method gives ids of dates that comes between start date and end date of calendar views :param order: The fields (comma separated, format "FIELD {DESC|ASC}") on which the events should be sorted
  • get_search_fields(self, order_fields, r_date=None)
    @api.multi
  • message_post(self, **kwargs)
    @api.multi@api.returns('mail.message', <expr>)
  • message_subscribe(self, partner_ids=None, channel_ids=None, subtype_ids=None)
    @api.multi
  • message_unsubscribe(self, partner_ids=None, channel_ids=None)
    @api.multi
  • read(self, fields=None, load='_classic_read')
    @api.multi
  • read_group(self, domain, fields, groupby, offset=0, limit=None, orderby=False, lazy=True)
    @api.model
  • unlink(self, can_be_deleted=True)
    @api.multi
  • write(self, values)
    @api.multi

New fields (1)
  • name Char
    required=True args: 'Name'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (1)
  • write(self, vals)
    @api.multi
    When posting an attachment (new or not), convert the virtual ids in real ids.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (1)
  • calendar_event_id Many2one → calendar.event
    ondelete='cascade' string='Calendar Meeting' args: 'calendar.event'
Public methods (3)
  • action_create_calendar_event(self)
    @api.multi
  • action_feedback(self, feedback=False)
  • unlink_w_meeting(self)

New fields (1)
  • category Selection
    selection_add=[('meeting', 'Meeting')]
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)
  • default_get(self, fields)
    @api.model
    In case someone clicked on 'invite others' wizard in the followers widget, transform virtual ids in real ids

New fields (1)
  • calendar_last_notif_ack Datetime
    default=fields.Datetime.now args: 'Last notification marked as read from base Calendar'
Public methods (1)
  • get_attendee_detail(self, meeting_id)
    @api.multi
    Return a list of tuple (id, name, status) Used by base_calendar.js : Many2ManyAttendee

New fields (0)

No new fields.

Public methods (1)
  • systray_get_activities(self)
    @api.model
REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/11.0/calendar
VERSION
VERSION 1.0
CATEGORY
CATEGORYExtra Tools
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONYes
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORS
MAINTAINERS
MAINTAINERS
COMMITTERS
COMMITTERSRaphael Collet, Odoo Translation Bot, Christophe Matthieu, Martin Trigaux, Olivier Dony, Thibault Delavallée, Denis Ledoux, Christophe Simonis, Xavier Morel, Goffin Simon, Nicolas Martinelli, Nicolas Lempereur, Jérome Maes, Richard Mathot, qdp-odoo, Aaron Bohy, Jeremy Kersten, GitHub, Lucas Perais (lpe), Olivier Colson, Yannick Tivisse, qsm-odoo, Martin Geubelle, Odoo Online, len-odoo, Jorge Pinna Puissant, Nans Lefebvre, Denis Vermylen, Andrea Grazioso (agr-odoo), Anh Thao Pham (pta)
WEBSITE
WEBSITEhttps://www.odoo.com/page/crm
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-05 23:53:43
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - base
    - mail
    - base_setup
    - web
    - bus
    - web_tour
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
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 (13)
XML IDNameModelTypeStatus
assets_backend calendar assets ir.ui.view qweb Inherits web.assets_backend
calendar_alarm_view_form calendar.alarm.form calendar.alarm form New
invitation_page_anonymous Calendar Invitation Page for anonymous users ir.ui.view qweb New
mail_activity_type_view_form mail.activity.type.form.inherit.calendar mail.activity.type xpath Inherits mail.mail_activity_type_view_form
mail_activity_view_form_popup mail.activity.form.inherit.calendar mail.activity xpath Inherits mail.mail_activity_view_form_popup
qunit_suite qunit_suite ir.ui.view qweb Inherits web.qunit_suite
view_calendar_alarm_tree calendar.alarm.tree calendar.alarm tree 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_popup calendar.event.form calendar.event form New
view_calendar_event_search calendar.event.search calendar.event search New
view_calendar_event_tree calendar.event.tree calendar.event tree New
view_calendar_event_type_tree calendar.event.type calendar.event.type tree New
Models touched (13)

New fields (5)
  • duration Integer
    default=1 required=True args: 'Remind Before'
  • duration_minutes Integer
    compute='_compute_duration_minutes' help='Duration in minutes' store=True args: 'Duration in minutes'
  • interval Selection
    default='hours' required=True args: list(_interval_selection.items()), 'Unit'
  • name Char
    required=True translate=True args: 'Name'
  • type Selection
    default='email' required=True args: [('notification', 'Notification'), ('email', 'Email')], 'Type'
Public methods (3)
  • create(self, values)
    @api.model
  • unlink(self)
    @api.multi
  • write(self, values)
    @api.multi

New fields (0)

No new fields.

Public methods (7)
  • 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_mail_reminder(self, alert)
  • do_notif_reminder(self, alert)
  • get_next_mail(self)
    @api.model
  • get_next_notif(self)
    @api.model
  • get_next_potential_limit_alarm(self, alarm_type, seconds=None, partner_id=None)
  • notify_next_alarm(self, partner_ids)
    Sends through the bus the next alarm of given partners

New fields (7)
  • access_token Char
    default=_default_access_token args: 'Invitation Token'
  • availability Selection
    readonly='True' args: [('free', 'Free'), ('busy', 'Busy')], 'Free/Busy'
  • common_name Char
    compute='_compute_common_name' store=True args: 'Common name'
  • email Char
    help='Email of Invited Person' args: 'Email'
  • event_id Many2one → calendar.event
    ondelete='cascade' args: 'calendar.event', 'Meeting linked'
  • partner_id Many2one → res.partner
    readonly='True' args: 'res.partner', 'Contact'
  • state Selection
    default='needsAction' help="Status of the attendee's participation" readonly=True string='Status' args: STATE_SELECTION
Public methods (5)
  • copy(self, default=None)
    @api.multi
  • create(self, values)
    @api.model
  • do_accept(self)
    @api.multi
    Marks event invitation as Accepted.
  • do_decline(self)
    @api.multi
    Marks event invitation as Declined.
  • do_tentative(self)
    @api.multi
    Makes event invitation as Tentative.

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

New fields (50)
  • 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.' args: 'Active'
  • activity_ids One2many → mail.activity
    string='Activities' args: 'mail.activity', 'calendar_event_id'
  • alarm_ids Many2many → calendar.alarm
    copy=False ondelete='restrict' string='Reminders' args: 'calendar.alarm', 'calendar_alarm_calendar_event_rel'
  • allday Boolean
    default=False states={'done': [('readonly', True)]} args: 'All Day'
  • attendee_ids One2many → calendar.attendee
    ondelete='cascade' args: 'calendar.attendee', 'event_id', 'Participant'
  • attendee_status Selection
    compute='_compute_attendee' string='Attendee Status' args: Attendee.STATE_SELECTION
  • byday Selection
    string='By day' args: [('1', 'First'), ('2', 'Second'), ('3', 'Third'), ('4', 'Fourth'), ('5', 'Fifth'), ('-1', 'Last')]
  • categ_ids Many2many → calendar.event.type
    args: 'calendar.event.type', 'meeting_category_rel', 'event_id', 'type_id', 'Tags'
  • count Integer
    default=1 help='Repeat x times' string='Repeat'
  • day Integer
    default=1 args: 'Date of month'
  • description Text
    states={'done': [('readonly', True)]} args: 'Description'
  • display_start Char
    compute='_compute_display_start' store=True args: 'Date'
  • display_time Char
    compute='_compute_display_time' args: 'Event Time'
  • duration Float
    states={'done': [('readonly', True)]} args: 'Duration'
  • end_type Selection
    default='count' string='Recurrence Termination' args: [('count', 'Number of repetitions'), ('end_date', 'End date')]
  • final_date Date
    args: 'Repeat Until'
  • fr Boolean
    args: 'Fri'
  • interval Integer
    default=1 help='Repeat every (Days/Week/Month/Year)' string='Repeat Every'
  • is_attendee Boolean
    compute='_compute_attendee' args: 'Attendee'
  • is_highlighted Boolean
    compute='_compute_is_highlighted' string='Is the Event Highlighted'
  • location Char
    help='Location of Event' states={'done': [('readonly', True)]} track_visibility='onchange' args: 'Location'
  • mo Boolean
    args: 'Mon'
  • month_by Selection
    default='date' oldname='select1' string='Option' args: [('date', 'Date of month'), ('day', 'Day of month')]
  • name Char
    required=True states={'done': [('readonly', True)]} args: 'Meeting Subject'
  • partner_id Many2one → res.partner
    readonly=True related='user_id.partner_id' string='Responsible' args: 'res.partner'
  • partner_ids Many2many → res.partner
    default=_default_partners states={'done': [('readonly', True)]} string='Attendees' args: 'res.partner', 'calendar_event_res_partner_rel'
  • privacy Selection
    default='public' oldname='class' states={'done': [('readonly', True)]} args: [('public', 'Everyone'), ('private', 'Only me'), ('confidential', 'Only internal users')], 'Privacy'
  • recurrency Boolean
    help='Recurrent Meeting' args: 'Recurrent'
  • recurrent_id Integer
    args: 'Recurrent ID'
  • recurrent_id_date Datetime
    args: 'Recurrent ID date'
  • res_id Integer
    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'
  • rrule Char
    compute='_compute_rrule' inverse='_inverse_rrule' store=True args: 'Recurrent Rule'
  • rrule_type Selection
    help='Let the event automatically repeat at that interval' states={'done': [('readonly', True)]} string='Recurrence' args: [('daily', 'Day(s)'), ('weekly', 'Week(s)'), ('monthly', 'Month(s)'), ('yearly', 'Year(s)')]
  • sa Boolean
    args: 'Sat'
  • show_as Selection
    default='busy' states={'done': [('readonly', True)]} args: [('free', 'Free'), ('busy', 'Busy')], 'Show Time as'
  • start Datetime
    help='Start date of an event, without time for full days events' required=True args: 'Start'
  • start_date Date
    compute='_compute_dates' inverse='_inverse_dates' states={'done': [('readonly', True)]} store=True track_visibility='onchange' args: 'Start Date'
  • start_datetime Datetime
    compute='_compute_dates' inverse='_inverse_dates' states={'done': [('readonly', True)]} store=True track_visibility='onchange' args: 'Start DateTime'
  • state Selection
    default='draft' readonly=True string='Status' track_visibility='onchange' args: [('draft', 'Unconfirmed'), ('open', 'Confirmed')]
  • stop Datetime
    help='Stop date of an event, without time for full days events' required=True args: 'Stop'
  • stop_date Date
    compute='_compute_dates' inverse='_inverse_dates' states={'done': [('readonly', True)]} store=True track_visibility='onchange' args: 'End Date'
  • stop_datetime Datetime
    compute='_compute_dates' inverse='_inverse_dates' states={'done': [('readonly', True)]} store=True track_visibility='onchange' args: 'End Datetime'
  • su Boolean
    args: 'Sun'
  • th Boolean
    args: 'Thu'
  • tu Boolean
    args: 'Tue'
  • user_id Many2one → res.users
    default=<expr> states={'done': [('readonly', True)]} args: 'res.users', 'Responsible'
  • we Boolean
    args: 'Wed'
  • week_list Selection
    string='Weekday' args: [('MO', 'Monday'), ('TU', 'Tuesday'), ('WE', 'Wednesday'), ('TH', 'Thursday'), ('FR', 'Friday'), ('SA', 'Saturday'), ('SU', 'Sunday')]
Public methods (23)
  • action_detach_recurring_event(self)
    @api.multi
  • action_open_calendar_event(self)
    @api.multi
  • action_sendmail(self)
    @api.multi
  • copy(self, default=None)
    @api.multi
  • create(self, values)
    @api.model
  • create_attendees(self)
    @api.multi
  • default_get(self, fields)
    @api.model
  • detach_recurring_event(self, values=None)
    @api.multi
    Detach a virtual recurring event by duplicating the original and change reccurent values :param values : dict of value to override on the detached event
  • export_data(self, fields_to_export, raw_data=False)
    @api.multi
    Override to convert virtual ids to ids
  • get_display_time_tz(self, tz=False)
    @api.multi
    get the display_time of the meeting, forcing the timezone. This method is called from email template, to not use sudo().
  • get_ics_file(self)
    @api.multi
    Returns iCalendar file for the event invitation. :returns a dict of .ics file content for each meeting
  • get_interval(self, interval, tz=None)
    @api.multi
    Format and localize some dates to be used in email templates :param string interval: Among 'day', 'month', 'dayname' and 'time' indicating the desired formatting :param string tz: Timezone indicator (optional) :return unicode: Formatted date or time (as unicode string, to prevent jinja2 crash)
  • get_metadata(self)
    @api.multi
  • get_recurrent_ids(self, domain, order=None)
    @api.multi
    Gives virtual event ids for recurring events. This method gives ids of dates that comes between start date and end date of calendar views :param order: The fields (comma separated, format "FIELD {DESC|ASC}") on which the events should be sorted
  • get_search_fields(self, order_fields, r_date=None)
    @api.multi
  • message_post(self, **kwargs)
    @api.multi@api.returns('self', <expr>)
  • message_subscribe(self, partner_ids=None, channel_ids=None, subtype_ids=None, force=True)
    @api.multi
  • message_unsubscribe(self, partner_ids=None, channel_ids=None)
    @api.multi
  • read(self, fields=None, load='_classic_read')
    @api.multi
  • read_group(self, domain, fields, groupby, offset=0, limit=None, orderby=False, lazy=True)
    @api.model
  • search(self, args, offset=0, limit=0, order=None, count=False)
    @api.model
  • unlink(self, can_be_deleted=True)
    @api.multi
  • write(self, values)
    @api.multi

New fields (1)
  • name Char
    required=True args: 'Name'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (2)
  • search(self, args, offset=0, limit=0, order=None, count=False)
    @api.model
    Convert the search on real ids in the case it was asked on virtual ids, then call super()
  • write(self, vals)
    @api.multi
    When posting an attachment (new or not), convert the virtual ids in real ids.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (1)
  • calendar_event_id Many2one → calendar.event
    ondelete='cascade' string='Calendar Meeting' args: 'calendar.event'
Public methods (3)
  • action_create_calendar_event(self)
    @api.multi
  • action_feedback(self, feedback=False)
  • unlink_w_meeting(self)

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

No public methods.

New fields (0)

No new fields.

Public methods (1)
  • search(self, args, offset=0, limit=0, order=None, count=False)
    @api.model
    Convert the search on real ids in the case it was asked on virtual ids, then call super()

New fields (0)

No new fields.

Public methods (1)
  • default_get(self, fields)
    @api.model
    In case someone clicked on 'invite others' wizard in the followers widget, transform virtual ids in real ids

New fields (1)
  • calendar_last_notif_ack Datetime
    default=fields.Datetime.now args: 'Last notification marked as read from base Calendar'
Public methods (1)
  • get_attendee_detail(self, meeting_id)
    @api.multi
    Return a list of tuple (id, name, status) Used by base_calendar.js : Many2ManyAttendee
REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/10.0/calendar
VERSION
VERSION 1.0
CATEGORY
CATEGORYExtra Tools
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONYes
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORS
MAINTAINERS
MAINTAINERS
COMMITTERS
COMMITTERSRaphael Collet, Odoo Translation Bot, Christophe Matthieu, Martin Trigaux, Fabien Pinckaers, Olivier Dony, Thibault Delavallée, Denis Ledoux, Christophe Simonis, Goffin Simon, Simon Lejeune, Nicolas Martinelli, Nicolas Lempereur, Jérome Maes, Julien Legros, qdp-odoo, Aaron Bohy, Jeremy Kersten, GitHub, Olivier Colson, Yannick Tivisse, qsm-odoo, Martin Geubelle, Pierre Masereel, RomainLibert, len-odoo, Adrian Torres
WEBSITE
WEBSITEhttps://www.odoo.com/page/crm
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-05 23:50:48
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - base
    - mail
    - base_setup
    - web_kanban
    - web
    - bus
    - web_tour
    - base_action_rule
    - resource
    - web_calendar
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
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 (10)
XML IDNameModelTypeStatus
assets_backend calendar assets ir.ui.view qweb Inherits web.assets_backend
calendar_alarm_view_form calendar.alarm.form calendar.alarm form New
invitation_page_anonymous Calendar Invitation Page for anonymous users ir.ui.view qweb New
view_calendar_alarm_tree calendar.alarm.tree calendar.alarm tree 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_popup calendar.event.form calendar.event form New
view_calendar_event_search calendar.event.search calendar.event search New
view_calendar_event_tree calendar.event.tree calendar.event tree New
view_calendar_event_type_tree calendar.event.type calendar.event.type tree New
Models touched (12)

New fields (5)
  • duration Integer
    default=1 required=True args: 'Amount'
  • duration_minutes Integer
    compute='_compute_duration_minutes' help='Duration in minutes' store=True args: 'Duration in minutes'
  • interval Selection
    default='hours' required=True args: list(_interval_selection.iteritems()), 'Unit'
  • name Char
    required=True args: 'Name'
  • type Selection
    default='email' required=True args: [('notification', 'Notification'), ('email', 'Email')], 'Type'
Public methods (3)
  • create(self, values)
    @api.model
  • unlink(self)
    @api.multi
  • write(self, values)
    @api.multi

New fields (0)

No new fields.

Public methods (7)
  • 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_mail_reminder(self, alert)
  • do_notif_reminder(self, alert)
  • get_next_mail(self)
    @api.model
  • get_next_notif(self)
    @api.model
  • get_next_potential_limit_alarm(self, alarm_type, seconds=None, partner_id=None)
  • notify_next_alarm(self, partner_ids)
    Sends through the bus the next alarm of given partners

New fields (7)
  • access_token Char
    default=_default_access_token args: 'Invitation Token'
  • availability Selection
    readonly='True' args: [('free', 'Free'), ('busy', 'Busy')], 'Free/Busy'
  • common_name Char
    compute='_compute_common_name' store=True args: 'Common name'
  • email Char
    help='Email of Invited Person' args: 'Email'
  • event_id Many2one → calendar.event
    ondelete='cascade' args: 'calendar.event', 'Meeting linked'
  • partner_id Many2one → res.partner
    readonly='True' args: 'res.partner', 'Contact'
  • state Selection
    default='needsAction' help="Status of the attendee's participation" readonly=True string='Status' args: STATE_SELECTION
Public methods (5)
  • copy(self, default=None)
    @api.multi
  • create(self, values)
    @api.model
  • do_accept(self)
    @api.multi
    Marks event invitation as Accepted.
  • do_decline(self)
    @api.multi
    Marks event invitation as Declined.
  • do_tentative(self)
    @api.multi
    Makes event invitation as Tentative.

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

New fields (45)
  • 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.' args: 'Active'
  • alarm_ids Many2many → calendar.alarm
    copy=False ondelete='restrict' string='Reminders' args: 'calendar.alarm', 'calendar_alarm_calendar_event_rel'
  • allday Boolean
    default=False states={'done': [('readonly', True)]} args: 'All Day'
  • attendee_ids One2many → calendar.attendee
    ondelete='cascade' args: 'calendar.attendee', 'event_id', 'Participant'
  • attendee_status Selection
    compute='_compute_attendee' string='Attendee Status' args: Attendee.STATE_SELECTION
  • byday Selection
    string='By day' args: [('1', 'First'), ('2', 'Second'), ('3', 'Third'), ('4', 'Fourth'), ('5', 'Fifth'), ('-1', 'Last')]
  • categ_ids Many2many → calendar.event.type
    args: 'calendar.event.type', 'meeting_category_rel', 'event_id', 'type_id', 'Tags'
  • color_partner_id Integer
    compute='_compute_color_partner' store=False args: 'Color index of creator'
  • count Integer
    default=1 help='Repeat x times' string='Repeat'
  • day Integer
    default=1 args: 'Date of month'
  • description Text
    states={'done': [('readonly', True)]} args: 'Description'
  • display_start Char
    compute='_compute_display_start' store=True args: 'Date'
  • display_time Char
    compute='_compute_display_time' args: 'Event Time'
  • duration Float
    states={'done': [('readonly', True)]} args: 'Duration'
  • end_type Selection
    default='count' string='Recurrence Termination' args: [('count', 'Number of repetitions'), ('end_date', 'End date')]
  • final_date Date
    args: 'Repeat Until'
  • fr Boolean
    args: 'Fri'
  • interval Integer
    default=1 help='Repeat every (Days/Week/Month/Year)' string='Repeat Every'
  • is_attendee Boolean
    compute='_compute_attendee' args: 'Attendee'
  • location Char
    help='Location of Event' states={'done': [('readonly', True)]} track_visibility='onchange' args: 'Location'
  • mo Boolean
    args: 'Mon'
  • month_by Selection
    default='date' oldname='select1' string='Option' args: [('date', 'Date of month'), ('day', 'Day of month')]
  • name Char
    required=True states={'done': [('readonly', True)]} args: 'Meeting Subject'
  • partner_ids Many2many → res.partner
    default=_default_partners states={'done': [('readonly', True)]} string='Attendees' args: 'res.partner', 'calendar_event_res_partner_rel'
  • privacy Selection
    default='public' oldname='class' states={'done': [('readonly', True)]} args: [('public', 'Everyone'), ('private', 'Only me'), ('confidential', 'Only internal users')], 'Privacy'
  • recurrency Boolean
    help='Recurrent Meeting' args: 'Recurrent'
  • recurrent_id Integer
    args: 'Recurrent ID'
  • recurrent_id_date Datetime
    args: 'Recurrent ID date'
  • rrule Char
    compute='_compute_rrule' inverse='_inverse_rrule' store=True args: 'Recurrent Rule'
  • rrule_type Selection
    help='Let the event automatically repeat at that interval' states={'done': [('readonly', True)]} string='Recurrence' args: [('daily', 'Day(s)'), ('weekly', 'Week(s)'), ('monthly', 'Month(s)'), ('yearly', 'Year(s)')]
  • sa Boolean
    args: 'Sat'
  • show_as Selection
    default='busy' states={'done': [('readonly', True)]} args: [('free', 'Free'), ('busy', 'Busy')], 'Show Time as'
  • start Datetime
    help='Start date of an event, without time for full days events' required=True args: 'Start'
  • start_date Date
    compute='_compute_dates' inverse='_inverse_dates' states={'done': [('readonly', True)]} store=True track_visibility='onchange' args: 'Start Date'
  • start_datetime Datetime
    compute='_compute_dates' inverse='_inverse_dates' states={'done': [('readonly', True)]} store=True track_visibility='onchange' args: 'Start DateTime'
  • state Selection
    default='draft' readonly=True string='Status' track_visibility='onchange' args: [('draft', 'Unconfirmed'), ('open', 'Confirmed')]
  • stop Datetime
    help='Stop date of an event, without time for full days events' required=True args: 'Stop'
  • stop_date Date
    compute='_compute_dates' inverse='_inverse_dates' states={'done': [('readonly', True)]} store=True track_visibility='onchange' args: 'End Date'
  • stop_datetime Datetime
    compute='_compute_dates' inverse='_inverse_dates' states={'done': [('readonly', True)]} store=True track_visibility='onchange' args: 'End Datetime'
  • su Boolean
    args: 'Sun'
  • th Boolean
    args: 'Thu'
  • tu Boolean
    args: 'Tue'
  • user_id Many2one → res.users
    default=<expr> states={'done': [('readonly', True)]} args: 'res.users', 'Responsible'
  • we Boolean
    args: 'Wed'
  • week_list Selection
    string='Weekday' args: [('MO', 'Monday'), ('TU', 'Tuesday'), ('WE', 'Wednesday'), ('TH', 'Thursday'), ('FR', 'Friday'), ('SA', 'Saturday'), ('SU', 'Sunday')]
Public methods (21)
  • action_detach_recurring_event(self)
    @api.multi
  • action_sendmail(self)
    @api.multi
  • copy(self, default=None)
    @api.multi
  • create(self, values)
    @api.model
  • create_attendees(self)
    @api.multi
  • detach_recurring_event(self, values=None)
    @api.multi
    Detach a virtual recurring event by duplicating the original and change reccurent values :param values : dict of value to override on the detached event
  • export_data(self, fields_to_export, raw_data=False)
    @api.multi
    Override to convert virtual ids to ids
  • get_display_time_tz(self, tz=False)
    @api.multi
    get the display_time of the meeting, forcing the timezone. This method is called from email template, to not use sudo().
  • get_ics_file(self)
    @api.multi
    Returns iCalendar file for the event invitation. :returns a dict of .ics file content for each meeting
  • get_interval(self, interval, tz=None)
    @api.multi
    Format and localize some dates to be used in email templates :param string interval: Among 'day', 'month', 'dayname' and 'time' indicating the desired formatting :param string tz: Timezone indicator (optional) :return unicode: Formatted date or time (as unicode string, to prevent jinja2 crash)
  • get_metadata(self)
    @api.multi
  • get_recurrent_ids(self, domain, order=None)
    @api.multi
    Gives virtual event ids for recurring events. This method gives ids of dates that comes between start date and end date of calendar views :param order: The fields (comma separated, format "FIELD {DESC|ASC}") on which the events should be sorted
  • get_search_fields(self, order_fields, r_date=None)
    @api.multi
  • message_post(self, **kwargs)
    @api.multi@api.returns('self', <expr>)
  • message_subscribe(self, partner_ids=None, channel_ids=None, subtype_ids=None, force=True)
    @api.multi
  • message_unsubscribe(self, partner_ids=None, channel_ids=None)
    @api.multi
  • read(self, fields=None, load='_classic_read')
    @api.multi
  • read_group(self, domain, fields, groupby, offset=0, limit=None, orderby=False, lazy=True)
    @api.model
  • search(self, args, offset=0, limit=0, order=None, count=False)
    @api.model
  • unlink(self, can_be_deleted=True)
    @api.multi
  • write(self, values)
    @api.multi

New fields (1)
  • name Char
    required=True args: 'Name'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (2)
  • search(self, args, offset=0, limit=0, order=None, count=False)
    @api.model
    Convert the search on real ids in the case it was asked on virtual ids, then call super()
  • write(self, vals)
    @api.multi
    When posting an attachment (new or not), convert the virtual ids in real ids.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (2)
  • get_actions(self, action_slot, model, res_id=False)
    @api.model@tools.ormcache_context('self._uid', 'action_slot', 'model', 'res_id', keys=('lang'))
  • set_action(self, name, action_slot, model, action, res_id=False)
    @api.model@api.returns('self', <expr>)

New fields (0)

No new fields.

Public methods (1)
  • search(self, args, offset=0, limit=0, order=None, count=False)
    @api.model
    Convert the search on real ids in the case it was asked on virtual ids, then call super()

New fields (0)

No new fields.

Public methods (1)
  • default_get(self, fields)
    @api.model
    In case someone clicked on 'invite others' wizard in the followers widget, transform virtual ids in real ids

New fields (1)
  • calendar_last_notif_ack Datetime
    args: 'Last notification marked as read from base Calendar'
Public methods (1)
  • get_attendee_detail(self, meeting_id)
    @api.multi
    Return a list of tuple (id, name, status) Used by web_calendar.js : Many2ManyAttendee
REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/9.0/calendar
VERSION
VERSION 1.0
CATEGORY
CATEGORYExtra Tools
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONYes
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORS
MAINTAINERS
MAINTAINERS
COMMITTERS
COMMITTERSOdoo Translation Bot, Christophe Matthieu, Martin Trigaux, Fabien Pinckaers, Antony Lesuisse, Olivier Dony, Thibault Delavallée, Denis Ledoux, Christophe Simonis, David Monjoie, Xavier Morel, Goffin Simon, Simon Lejeune, Nicolas Martinelli, Nicolas Lempereur, Jérome Maes, Julien Legros, Richard Mathot, Géry Debongnie, Aaron Bohy, Lucas Perais (lpe), Damien Bouvy, Julien De Coster, Yannick Tivisse, qsm-odoo
WEBSITE
WEBSITEhttps://www.odoo.com/page/crm
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-05 23:48:30
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - base
    - mail
    - base_setup
    - web_kanban
    - web
    - bus
    - base_action_rule
    - resource
    - web_calendar
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
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 (9)
XML IDNameModelTypeStatus
assets_backend calendar assets ir.ui.view qweb Inherits web.assets_backend
calendar_alarm_view_form calendar.alarm.form calendar.alarm form New
view_calendar_alarm_tree Calendar Alarm Tree calendar.alarm tree New
view_calendar_event_calendar Meeting calendar.event calendar New
view_calendar_event_form Calendar - Event Form calendar.event form New
view_calendar_event_form_popup Meetings Dialog calendar.event form New
view_calendar_event_search CRM - Meetings Search calendar.event search New
view_calendar_event_tree CRM - Meetings Tree calendar.event tree New
view_calendar_event_type_tree Meeting Types Tree calendar.event.type tree New
Models touched (10)

New fields (0)

No new fields.

Public methods (4)
  • create(self, cr, uid, values, context=None)
  • onchange_duration_interval(self, cr, uid, ids, duration, interval, context=None)
  • unlink(self, cr, uid, ids, context=None)
  • write(self, cr, uid, ids, values, context=None)

New fields (0)

No new fields.

Public methods (6)
  • do_check_alarm_for_one_date(self, cr, uid, one_date, event, event_maxdelta, in_the_next_X_seconds, after=False, notif=True, mail=True, missing=False, context=None)
  • do_mail_reminder(self, cr, uid, alert, context=None)
  • do_notif_reminder(self, cr, uid, alert, context=None)
  • get_next_mail(self, cr, uid, context=None)
  • get_next_notif(self, cr, uid, context=None)
  • get_next_potential_limit_alarm(self, cr, uid, seconds, notif=True, mail=True, partner_id=None, context=None)

New fields (0)

No new fields.

Public methods (8)
  • copy(self, cr, uid, id, default=None, context=None)
  • create(self, cr, uid, vals, context=None)
  • do_accept(self, cr, uid, ids, context=None, *args)
    Marks event invitation as Accepted. @param ids: list of attendee's IDs
  • do_decline(self, cr, uid, ids, context=None, *args)
    Marks event invitation as Declined. @param ids: list of calendar attendee's IDs
  • do_tentative(self, cr, uid, ids, context=None, *args)
    Makes event invitation as Tentative. @param ids: list of attendee's IDs
  • get_ics_file(self, cr, uid, event_obj, context=None)
    Returns iCalendar file for the event invitation. @param event_obj: event object (browse record) @return: .ics file content
  • onchange_partner_id(self, cr, uid, ids, partner_id, context=None)
    Make entry on email and availability on change of partner_id field. @param partner_id: changed value of partner id
  • onchange_user_id(self, cr, uid, ids, user_id, *args, **argv)
    Make entry on email and availability on change of user_id field. @param ids: list of attendee's IDs @param user_id: changed value of User id @return: dictionary of values which put value in email and availability fields

New fields (0)

No new fields.

Public methods (30)
  • check_partners_email(self, cr, uid, partner_ids, context=None)
    Verify that selected partner_ids have an email_address defined. Otherwise throw a warning.
  • compute_rule_string(self, data)
    Compute rule string according to value type RECUR of iCalendar from the values given. @param self: the object pointer @param data: dictionary of freq and interval value @return: string containing recurring rule (empty if no rule)
  • copy(self, cr, uid, id, default=None, context=None)
  • create(self, cr, uid, vals, context=None)
  • create_attendees(self, cr, uid, ids, context=None)
  • do_run_scheduler(self, cr, uid, id, context=None)
  • do_sendmail(self, cr, uid, ids, context=None)
  • export_data(self, cr, uid, ids, *args, **kwargs)
    Override to convert virtual ids to ids
  • get_attendee(self, cr, uid, meeting_id, context=None)
  • get_date_formats(self, cr, uid, context)
  • get_display_time_tz(self, cr, uid, ids, tz=False, context=None)
  • get_interval(self, cr, uid, ids, date, interval, tz=None, context=None)
    Format and localize some dates to be used in email templates :param string date: date/time to be formatted :param string interval: Among 'day', 'month', 'dayname' and 'time' indicating the desired formatting :param string tz: Timezone indicator (optional) :return unicode: Formatted date or time (as unicode string, to prevent jinja2 crash) (Function used only in calendar_event_data.xml)
  • get_metadata(self)
    @api.multi
  • get_recurrent_date_by_event(self, cr, uid, event, context=None)
  • get_recurrent_ids(self, cr, uid, event_id, domain, order=None, context=None)
    Gives virtual event ids for recurring events This method gives ids of dates that comes between start date and end date of calendar views @param order: The fields (comma separated, format "FIELD {DESC|ASC}") on which the events should be sorted
  • get_search_fields(self, browse_event, order_fields, r_date=None)
  • message_post(self, cr, uid, thread_id, context=None, **kwargs)
    @api.cr_uid_ids_context@api.returns('mail.message', <expr>)
  • message_subscribe(self, cr, uid, ids, partner_ids=None, channel_ids=None, subtype_ids=None, force=True, context=None)
  • message_unsubscribe(self, cr, uid, ids, partner_ids=None, channel_ids=None, context=None)
  • new_invitation_token(self, cr, uid, record, partner_id)
  • onchange_allday(self, cr, uid, ids, start=False, end=False, starttime=False, endtime=False, startdatetime=False, enddatetime=False, checkallday=False, context=None)
  • onchange_dates(self, cr, uid, ids, fromtype, start=False, end=False, checkallday=False, allday=False, context=None)
    Returns duration and end date based on values passed @param ids: List of calendar event's IDs.
  • onchange_duration(self, cr, uid, ids, start=False, duration=False, context=None)
  • onchange_partner_ids(self, cr, uid, ids, value, context=None)
    The basic purpose of this method is to check that destination partners effectively have email addresses. Otherwise a warning is thrown. :param value: value format: [[6, 0, [3, 4]]]
  • open_after_detach_event(self, cr, uid, ids, context=None)
  • read(self, cr, uid, ids, fields=None, context=None, load='_classic_read')
  • read_group(self, cr, uid, domain, fields, groupby, offset=0, limit=None, context=None, orderby=False, lazy=True)
  • search(self, cr, uid, args, offset=0, limit=0, order=None, context=None, count=False)
  • unlink(self, cr, uid, ids, can_be_deleted=True, context=None)
  • write(self, cr, uid, ids, values, context=None)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (2)
  • search(self, cr, uid, args, offset=0, limit=0, order=None, context=None, count=False)
    convert the search on real ids in the case it was asked on virtual ids, then call super()
  • write(self, cr, uid, ids, vals, context=None)
    when posting an attachment (new or not), convert the virtual ids in real ids.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (2)
  • get(self, cr, uid, key, key2, models, meta=False, context=None, res_id_req=False, without_user=True, key2_req=True)
  • set(self, cr, uid, key, key2, name, models, value, replace=True, isobject=False, meta=False, preserve_user=False, company=False)

New fields (0)

No new fields.

Public methods (1)
  • search(self, cr, uid, args, offset=0, limit=0, order=None, context=None, count=False)
    convert the search on real ids in the case it was asked on virtual ids, then call super()

New fields (0)

No new fields.

Public methods (1)
  • get_attendee_detail(self, cr, uid, ids, meeting_id, context=None)
    Return a list of tuple (id, name, status) Used by web_calendar.js : Many2ManyAttendee
REPOSITORY
REPOSITORYodoo/odoo
GIT
GIThttps://github.com/odoo/odoo.git
GIT FOLDER
GIT FOLDERhttps://github.com/odoo/odoo/tree/8.0/calendar
VERSION
VERSION 1.0
CATEGORY
CATEGORYHidden/Dependency
LICENSE
LICENSELGPL-3
APPLICATION
APPLICATIONYes
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOpenERP SA
MAINTAINERS
MAINTAINERSOpenERP SA
COMMITTERS
COMMITTERSRaphael Collet, Atul Patel (OpenERP), Odoo Translation Bot, Martin Trigaux, Fabien Pinckaers, Antony Lesuisse, Olivier Dony, Thibault Delavallée, Josse Colpaert, Launchpad Translations on behalf of openerp, Denis Ledoux, Fabien Meghazi, Christophe Simonis, Xavier Morel, Goffin Simon, Simon Lejeune, Nicolas Martinelli, Kersten Jeremy, Nicolas Lempereur, Julien Legros, Richard Mathot, qdp-odoo, Géry Debongnie, jke-openerp, Aaron Bohy, Richard Mathot (OpenERP), ged-odoo, Jeremy Kersten, Gery Debongnie, Martin Geubelle
WEBSITE
WEBSITEhttps://www.odoo.com/page/crm
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-05 23:45:39
ODOO DEPENDENCIES
ODOO DEPENDENCIES odoo/odoo:
    - base
    - mail
    - base_setup
    - web_kanban
    - web
    - base_action_rule
    - resource
    - web_calendar
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES Not have
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
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 (9)
XML IDNameModelTypeStatus
assets_backend calendar assets ir.ui.view qweb Inherits web.assets_backend
view_calendar_alarm_tree Calendar Alarm Tree calendar.alarm tree New
view_calendar_event_calendar Meetings Calendar calendar.event calendar New
view_calendar_event_form Calendar - Event Form calendar.event form New
view_calendar_event_form_popup Meetings Popup calendar.event form New
view_calendar_event_gantt CRM - Meetings Gantt calendar.event gantt New
view_calendar_event_search CRM - Meetings Search calendar.event search New
view_calendar_event_tree CRM - Meetings Tree calendar.event tree New
view_calendar_event_type_tree Meeting Types Tree calendar.event.type tree New
Models touched (11)

New fields (0)

No new fields.

Public methods (3)
  • create(self, cr, uid, values, context=None)
  • unlink(self, cr, uid, ids, context=None)
  • write(self, cr, uid, ids, values, context=None)

New fields (0)

No new fields.

Public methods (6)
  • do_check_alarm_for_one_date(self, cr, uid, one_date, event, event_maxdelta, in_the_next_X_seconds, after=False, notif=True, mail=True, missing=False, context=None)
  • do_mail_reminder(self, cr, uid, alert, context=None)
  • do_notif_reminder(self, cr, uid, alert, context=None)
  • get_next_mail(self, cr, uid, context=None)
  • get_next_notif(self, cr, uid, context=None)
  • get_next_potential_limit_alarm(self, cr, uid, seconds, notif=True, mail=True, partner_id=None, context=None)

New fields (0)

No new fields.

Public methods (8)
  • copy(self, cr, uid, id, default=None, context=None)
  • create(self, cr, uid, vals, context=None)
  • do_accept(self, cr, uid, ids, context=None, *args)
    Marks event invitation as Accepted. @param ids: list of attendee's IDs
  • do_decline(self, cr, uid, ids, context=None, *args)
    Marks event invitation as Declined. @param ids: list of calendar attendee's IDs
  • do_tentative(self, cr, uid, ids, context=None, *args)
    Makes event invitation as Tentative. @param ids: list of attendee's IDs
  • get_ics_file(self, cr, uid, event_obj, context=None)
    Returns iCalendar file for the event invitation. @param event_obj: event object (browse record) @return: .ics file content
  • onchange_partner_id(self, cr, uid, ids, partner_id, context=None)
    Make entry on email and availability on change of partner_id field. @param partner_id: changed value of partner id
  • onchange_user_id(self, cr, uid, ids, user_id, *args, **argv)
    Make entry on email and availability on change of user_id field. @param ids: list of attendee's IDs @param user_id: changed value of User id @return: dictionary of values which put value in email and availability fields

New fields (0)

No new fields.

Public methods (29)
  • check_partners_email(self, cr, uid, partner_ids, context=None)
    Verify that selected partner_ids have an email_address defined. Otherwise throw a warning.
  • compute_rule_string(self, data)
    Compute rule string according to value type RECUR of iCalendar from the values given. @param self: the object pointer @param data: dictionary of freq and interval value @return: string containing recurring rule (empty if no rule)
  • copy(self, cr, uid, id, default=None, context=None)
  • create(self, cr, uid, vals, context=None)
  • create_attendees(self, cr, uid, ids, context=None)
  • do_run_scheduler(self, cr, uid, id, context=None)
  • do_sendmail(self, cr, uid, ids, context=None)
  • export_data(self, cr, uid, ids, *args, **kwargs)
    Override to convert virtual ids to ids
  • get_attendee(self, cr, uid, meeting_id, context=None)
  • get_date_formats(self, cr, uid, context)
  • get_display_time_tz(self, cr, uid, ids, tz=False, context=None)
  • get_interval(self, cr, uid, ids, date, interval, tz=None, context=None)
    Format and localize some dates to be used in email templates :param string date: date/time to be formatted :param string interval: Among 'day', 'month', 'dayname' and 'time' indicating the desired formatting :param string tz: Timezone indicator (optional) :return unicode: Formatted date or time (as unicode string, to prevent jinja2 crash) (Function used only in calendar_event_data.xml)
  • get_recurrent_date_by_event(self, cr, uid, event, context=None)
    Get recurrent dates based on Rule string and all event where recurrent_id is child
  • get_recurrent_ids(self, cr, uid, event_id, domain, order=None, context=None)
    Gives virtual event ids for recurring events This method gives ids of dates that comes between start date and end date of calendar views @param order: The fields (comma separated, format "FIELD {DESC|ASC}") on which the events should be sorted
  • get_search_fields(self, browse_event, order_fields, r_date=None)
  • message_get_subscription_data(self, cr, uid, ids, user_pid=None, context=None)
  • message_post(self, cr, uid, thread_id, body='', subject=None, type='notification', subtype=None, parent_id=False, attachments=None, context=None, **kwargs)
    @api.cr_uid_ids_context
  • message_subscribe(self, cr, uid, ids, partner_ids, subtype_ids=None, context=None)
  • message_unsubscribe(self, cr, uid, ids, partner_ids, context=None)
  • new_invitation_token(self, cr, uid, record, partner_id)
  • onchange_allday(self, cr, uid, ids, start=False, end=False, starttime=False, endtime=False, startdatetime=False, enddatetime=False, checkallday=False, context=None)
  • onchange_dates(self, cr, uid, ids, fromtype, start=False, end=False, checkallday=False, allday=False, context=None)
    Returns duration and end date based on values passed @param ids: List of calendar event's IDs.
  • onchange_partner_ids(self, cr, uid, ids, value, context=None)
    The basic purpose of this method is to check that destination partners effectively have email addresses. Otherwise a warning is thrown. :param value: value format: [[6, 0, [3, 4]]]
  • open_after_detach_event(self, cr, uid, ids, context=None)
  • read(self, cr, uid, ids, fields=None, context=None, load='_classic_read')
  • read_group(self, cr, uid, domain, fields, groupby, offset=0, limit=None, context=None, orderby=False, lazy=True)
  • search(self, cr, uid, args, offset=0, limit=0, order=None, context=None, count=False)
  • unlink(self, cr, uid, ids, can_be_deleted=True, context=None)
  • write(self, cr, uid, ids, values, context=None)

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (2)
  • search(self, cr, uid, args, offset=0, limit=0, order=None, context=None, count=False)
    convert the search on real ids in the case it was asked on virtual ids, then call super()
  • write(self, cr, uid, ids, vals, context=None)
    when posting an attachment (new or not), convert the virtual ids in real ids.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (1)
  • read(self, cr, uid, ids, fields=None, context=None, load='_classic_read')

New fields (0)

No new fields.

Public methods (2)
  • get(self, cr, uid, key, key2, models, meta=False, context=None, res_id_req=False, without_user=True, key2_req=True)
  • set(self, cr, uid, key, key2, name, models, value, replace=True, isobject=False, meta=False, preserve_user=False, company=False)

New fields (0)

No new fields.

Public methods (1)
  • search(self, cr, uid, args, offset=0, limit=0, order=None, context=None, count=False)
    convert the search on real ids in the case it was asked on virtual ids, then call super()

New fields (0)

No new fields.

Public methods (1)
  • get_attendee_detail(self, cr, uid, ids, meeting_id, context=None)
    Return a list of tuple (id, name, status) Used by web_calendar.js : Many2ManyAttendee