Repository
odoo/odoo · module folder
Module version
1.19
Category
Productivity/Discuss
Folder size
43.38 MB
License
LGPL-3
Application
Yes
Auto-installable
No
Website
https://www.odoo.com/app/discuss
Last tracking update
2026-08-20 22:13:23
Authors
Odoo S.A.
Maintainers
Odoo S.A.
Committers
Xavier Morel, Xavier ALT, Raphael Collet, Thibault Delavallée, Stefan Rijnhart, odoo, Odoo Translation Bot, Denis Ledoux, David Monjoie, Nicolas Martinelli, Nicolas Lempereur, Aaron Bohy, Géry Debongnie, Jeremy Kersten, Lucas Perais (lpe), Damien Bouvy, Pierre Masereel, Christophe Monniez, Jorge Pinna Puissant, Jairo Llopis, Lucas Perais, Alexandre Kühn, Julien Castiaux, Xavier-Do, Romeo Fragomeli, Adrien Dieudonné, Paul Morelle, Sébastien Theys, Julien Mougenot, Anh Thao Pham (pta), std-odoo, Achraf (abz), Brice bib Bartoletti, Prakash Prajapati, Rémy Voet (ryv), Tiffany Chang (tic), Pierre Rousseau, ThanhDodeurOdoo, Gorash, Mathieu Duckerts-Antoine, Pierre Paridans, abd-msyukyu-odoo, William Braeckman, Romain Estievenart, Miquel Raïch, Stanislas Sobieski, william-andre, yhu-odoo, Didier (did), Nicolas Bayet, Jinjiu Liu, luvi, Hubert Van De Walle, Renaud Thiry, Julien Banken, bve-odoo, tsm-odoo, Louis Wicket (wil), alsh-odoo, Gaetan Vanden Bergh (gavb), Maximilien (malb), Victor Piryns (pivi), Thomas Becquevort (thbe), amdi-odoo, Pierre-Yves Dufays, Levi Siuzdak (sile), Dylan Kiss (dyki), Bruno Boi, FrancoisGe, Mayurrajsinh Rathod, Rahul Prajapati, Chong Wang (cwg), Leloup Loïc (lole), Adrien Schoffeniels, Xavier Bol (xbo), omra-odoo, Zelong Lin, Andrzej(pian), sesn-odoo, Walid (wasa), BHanq, Deependra Solanki, maad-odoo, aktr-odoo, Hesham, Youssef Bashandy, Maryam Kia, jorv-odoo, Maxime de Neuville, reka-odoo, “Beekan”, Ricardoalso, vava-odoo, Bruno Boi (boi), dhba, Julien Carion (juca), Bastien Fafchamps (bafa), adsh-odoo, mega, Tanguy Quéguineur, TSO, Alex Kühn, Lopes Marc (loma), nihp-odoo, adch-odoo, aath-odoo, Rodolpho Lima, Adnan Saiyed, Chrysanthe (chgo), Junqi Wu, mano-odoo, Joseph (jcb), thle-odoo, Mathieu Coutant, Xavier Luyckx (xlu), guce, yagp-odoo, Elisabeth Dickinson, haumenphai, rame-odoo, sabr, Antoine Dupuis, Pierre Pulinckx (PIPU), Sébastien (blse), Hesham Saleh, Julien Schwanen, quyen, Victor Miguel Armenta Carrillo, sben-odoo, Iván Todorovich, aych-odoo, Pierre Pulinckx, Anton Romanova (roan), Bastien PIERRE, nikj-odoo, Michaël Mattiello, masm-odoo, K Theja (kthe), zel-odoo, pish-odoo, Panagiotis Kyriakou, plha-odoo, Thomas Josse (THJO), Krzysztof Magusiak (krma), Ajit Singh, nees-odoo, Basioni (basm), sagu-odoo, kdes-odoo, Maeva De Keyser (MDEK), utma-odoo, mojem, pajo, Brett Cutler, defl, Ayush Chauhan (aych), Giorgio Tocco (gito), akha, jayp-odoo, romc-odoo, igbe, Tudor-Calin Panzaru (tupan), Laetitia (ldau), adip-odoo, Augustin (duau), Patrick Stooks, shka-odoo, Jérôme Belpaire, ramh, Waleed Elgamal, leclerc-leo, oumaima-aarabe, dhrp-odoo, Bruno BOI, assh-odoo, livaios, Jeremy Lawson (jelaw), Quoc - Pham Ngoc, Kevin Gerard (kege), Akash Parmar, Louis, pmah-odoo, nmak-odoo, Julian Heuser, Benoit Socias (bso), YoussefM890, Soumya M, saurabh, Omar Khalil (omkha), Julien Segers, Séna Nshimiyimana, Atovange, Zachary (zavan), Jan Suhr, alan-odoo, Jason (jaca), Kadam Darji, Julien (jdeh), ibo-odoo, raja prasad, Farah (ahmfa), akth-odoo, Mehdi Rachico (mera), akus-odoo, ELCO, karygauss03, Haja Ram, chpa-odoo, shmn-odoo, Claire Nguyen (clan), mear-odoo, Dylan Provoost, Mohamed Ayman, Louis Wicket, Joe VanHorn, alwhi-odoo, rsbh-odoo, Yusuf Köksal
Odoo dependencies
odoo/odoo:
- web
- bus
Python dependencies
None
System dependencies
None
Required by
account_credit_control, account_payment_return, agreement, analytic, auth_signup, auth_totp_mail, auto_backup, base_automation, base_comment_template, base_install_request, base_substate, base_tier_validation, base_user_signature, calendar, cloud_storage, connector, contacts, crm, currency_rate_update, data_recycle, developer_menu, digest, disable_odoo_online, document_page, document_page_approval, document_url, edi_core_oca, event, fleet, gamification, google_gmail, helpdesk_mgmt, hotel_reservation, hr_course, html_builder, iap_mail, im_livechat, l10n_fr_siret, lims, link_tracker, lunch, mail_activity_reminder, mail_activity_team, mail_attach_existing_attachment, mail_bot, mail_debranding, mail_environment, mail_forward, mail_group, mail_message_destiny_link_template, mail_message_search, mail_multicompany, mail_optional_autofollow, mail_partner_opt_out, mail_post_defer, mail_restrict_follower_selection, mail_restrict_send_button, mail_send_confirmation, mail_tracking, maintenance, mass_mailing, mgmtsystem_action, mgmtsystem_partner, microsoft_outlook, mute_notification_user_autosubscribe, partner_auto_archive, payroll, phone_validation, pms_base, portal, privacy_lookup, product, project, queue_job, rating, resource_booking, resource_mail, sales_team, scheduler_error_mailer, sms, snailmail, sql_request_abstract, survey, test_discuss_full, test_http, test_mail, test_mail_full, test_mail_sms, tms, tracking_manager, voip_oca, web_chatter_position, web_notify, web_responsive, website, website_mail
Description

Chat, mail gateway and private channel.
=======================================

Communicate with your colleagues/customers/guest within Odoo.

Discuss/Chat
------------
User-friendly "Discuss" features that allows one 2 one or group communication
(text chat/voice call/video call), invite guests and share documents with
them, all real-time.

Mail gateway
------------
Sending information and documents made simplified. You can send emails
from Odoo itself, and that too with great possibilities. For example,
design a beautiful email template for the invoices, and use the same
for all your customers, no need to do the same exercise every time.

Chatter
-------
Do all the contextual conversation on a document. For example on an
applicant, directly post an update to send email to the applicant,
schedule the next interview call, attach the contract, add HR officer
to the follower list to notify them for important events(with help of
subtypes),...


Retrieve incoming email on POP/IMAP servers.
============================================
Enter the parameters of your POP/IMAP account(s), and any incoming emails on
these accounts will be automatically downloaded into your Odoo system. All
POP3/IMAP-compatible servers are supported, included those that require an
encrypted SSL/TLS connection.
This can be used to easily create email-based workflows for many email-enabled Odoo documents, such as:
----------------------------------------------------------------------------------------------------------
    * CRM Leads/Opportunities
    * CRM Claims
    * Project Issues
    * Project Tasks
    * Human Resource Recruitment (Applicants)
Just install the relevant application, and you can assign any of these document
types (Leads, Project Issues) to your incoming email accounts. New emails will
automatically spawn new documents of the chosen type, so it's a snap to create a
mailbox-to-Odoo integration. Even better: these documents directly act as mini
conversations synchronized by email. You can reply from within Odoo, and the
answers will automatically be collected when they come back, and attached to the
same *conversation* document.
For more specific needs, you may also assign custom-defined actions
(technically: Server Actions) to be triggered for each incoming mail.
    

Code Analysis

Views touched (137)
XML IDNameModelTypeStatus
account_security_alert Alert Security Update ir.ui.view qweb New
discuss_call_history_view_form discuss.call.history.view.form discuss.call.history form New
discuss_call_history_view_tree discuss.call.history.view.list discuss.call.history list New
discuss_channel_invitation_template discuss_channel_invitation_template ir.ui.view qweb New
discuss_channel_member_view_form discuss.channel.member.form discuss.channel.member form New
discuss_channel_member_view_tree discuss.channel.member.list discuss.channel.member list New
discuss_channel_rtc_session_view_form discuss.channel.rtc.session.form discuss.channel.rtc.session form New
discuss_channel_rtc_session_view_search discuss.channel.rtc.session.search discuss.channel.rtc.session search New
discuss_channel_rtc_session_view_tree discuss.channel.rtc.session.list discuss.channel.rtc.session list New
discuss_gif_favorite_view_form discuss.gif.favorite.form discuss.gif.favorite form New
discuss_gif_favorite_view_tree discuss.gif.favorite.list discuss.gif.favorite list New
email_compose_message_wizard_form mail.compose.message.form mail.compose.message form New
email_template_form email.template.form mail.template form New
email_template_tree email.template.list mail.template list New
field_form_view ir.model.fields form Inherits base.view_model_fields_form
ir_cron_view_form ir.cron.view.form.inherit ir.cron form Inherits base.ir_cron_view_form
ir_filters_view_form ir.filters.view.form.inherit ir.filters form Inherits base.ir_filters_view_form
ir_filters_view_tree ir.filters.view.tree.inherit ir.filters tree Inherits base.ir_filters_view_tree
ir_mail_server_view_form ir.mail_server.view.form.inherit.mail ir.mail_server form Inherits base.ir_mail_server_form
mail.discuss_channel_view_form discuss.channel.form discuss.channel form New
mail.discuss_channel_view_kanban discuss.channel.kanban discuss.channel kanban New
mail.discuss_channel_view_list discuss.channel.list discuss.channel list New
mail.discuss_channel_view_search discuss.channel.search discuss.channel search New
mail.discuss_channel_view_tree discuss.channel.list discuss.channel list New
mail.discuss_public_channel_template Discuss Public Template ir.ui.view qweb New
mail.message_document_unfollowed mail.message_document_unfollowed ir.ui.view qweb New
mail.public_layout mail.public_layout ir.ui.view qweb New
mail_activity_plan_template_view_form mail.activity.plan.template.view.form mail.activity.plan.template form New
mail_activity_plan_template_view_tree mail.activity.plan.template.view.list mail.activity.plan.template list New
mail_activity_plan_view_form mail.activity.plan.view.form mail.activity.plan form New
mail_activity_plan_view_form_fixed_model mail.activity.plan.view.form.fixed.model mail.activity.plan form Inherits mail.mail_activity_plan_view_form
mail_activity_plan_view_kanban mail.activity.plan.view.kanban mail.activity.plan kanban New
mail_activity_plan_view_search mail.activity.plan.view.search mail.activity.plan search New
mail_activity_plan_view_tree mail.activity.plan.view.list mail.activity.plan list New
mail_activity_plan_view_tree_detailed mail.activity.plan.view.list.detailed mail.activity.plan list Inherits mail.mail_activity_plan_view_tree
mail_activity_schedule_view_form Activity schedule mail.activity.schedule form New
mail_activity_type_view_form mail.activity.type.view.form mail.activity.type form New
mail_activity_type_view_kanban mail.activity.type.view.kanban mail.activity.type kanban New
mail_activity_type_view_search mail.activity.type.search mail.activity.type search New
mail_activity_type_view_tree mail.activity.type.view.list mail.activity.type list New
mail_activity_view_calendar mail.activity.view.calendar mail.activity calendar New
mail_activity_view_form mail.activity.view.form mail.activity form Inherits mail.mail_activity_view_form_popup
mail_activity_view_form_popup mail.activity.view.form.popup mail.activity form New
mail_activity_view_form_without_record_access mail.activity.view.form.without.record.access mail.activity form New
mail_activity_view_kanban_open_target mail.activity.view.kanban.open.target mail.activity kanban New
mail_activity_view_search mail.activity.view.search mail.activity search New
mail_activity_view_tree mail.activity.view.list mail.activity list New
mail_activity_view_tree_open_target mail.activity.view.list.open.target mail.activity list Inherits mail_activity_view_tree
mail_activity_view_tree_without_record_access mail.activity.view.list.without.record.access mail.activity list Inherits mail_activity_view_tree
mail_alias_domain_view_form mail.alias.domain.view.form mail.alias.domain form New
mail_alias_domain_view_search mail.alias.domain.view.search mail.alias.domain search New
mail_alias_domain_view_tree mail.alias.domain.view.list mail.alias.domain list New
mail_alias_view_form mail.alias.view.form mail.alias form New
mail_alias_view_search mail.alias.view.search mail.alias search New
mail_alias_view_tree mail.alias.view.list mail.alias list New
mail_attachment_links Attachment links ir.ui.view qweb New
mail_blacklist_remove_view_form mail.blacklist.remove.form mail.blacklist.remove form New
mail_blacklist_view_form mail.blacklist.view.form mail.blacklist form New
mail_blacklist_view_search mail.blacklist.view.search mail.blacklist search New
mail_blacklist_view_tree mail.blacklist.view.list mail.blacklist list New
mail_bounce_alias_security mail_bounce_alias_security ir.ui.view qweb New
mail_bounce_catchall mail_bounce_catchall ir.ui.view qweb New
mail_canned_response_view_form mail.canned.response.form mail.canned.response form New
mail_canned_response_view_kanban mail.canned.response.kanban mail.canned.response kanban New
mail_canned_response_view_search mail.canned.response.view.search mail.canned.response search New
mail_canned_response_view_tree mail.canned.response.list mail.canned.response list New
mail_compose_message_view_form_template_save mail.compose.message.view.form.template.save mail.compose.message form New
mail_followers_edit_form mail.followers.edit.form mail.followers.edit form New
mail_followers_list_edit_form mail.followers.list.edit.form mail.followers.edit form Inherits mail_followers_edit_form
mail_gateway_allowed_view_search mail.gateway.allowed.view.search mail.gateway.allowed search New
mail_gateway_allowed_view_tree mail.gateway.allowed.view.list mail.gateway.allowed list New
mail_guest_view_form mail.guest.form mail.guest form New
mail_guest_view_tree mail.guest.list mail.guest list New
mail_link_preview_view_form mail.link.preview.form mail.link.preview form New
mail_link_preview_view_tree mail.link.preview.list mail.link.preview list New
mail_message_reaction_view_form mail.message.reaction.form mail.message.reaction form New
mail_message_reaction_view_tree mail.message.reaction.list mail.message.reaction list New
mail_message_schedule_view_form mail.message.schedule.view.form mail.message.schedule form New
mail_message_schedule_view_search mail.message.schedule.view.search mail.message.schedule search New
mail_message_schedule_view_tree mail.message.schedule.view.list mail.message.schedule list New
mail_message_subtype_view_search mail.message.subtype.view.search mail.message.subtype search New
mail_message_view_form mail.message.view.form mail.message form New
mail_notification_invite mail_notification_invite ir.ui.view qweb Inherits mail.mail_notification_layout
mail_notification_layout Mail: mail notification layout template ir.ui.view qweb New
mail_notification_layout_with_responsible_signature Mail: mail notification layout with responsible signature (user_id of the record) ir.ui.view qweb Inherits mail.mail_notification_layout
mail_notification_light mail_notification_light ir.ui.view qweb New
mail_notification_multi_invite mail_notification_multi_invite ir.ui.view qweb Inherits mail.mail_notification_invite
mail_notification_view_form mail.notification.view.form mail.notification form New
mail_notification_view_tree mail.notification.view.list mail.notification list New
mail_scheduled_message_view_form mail.scheduled.message.view.form mail.scheduled.message form New
mail_template_preview_view_form mail.template.preview.view.form mail.template.preview form New
mail_template_reset_view_form mail.template.reset.view.form mail.template.reset form New
message_activity_assigned message_activity_assigned ir.ui.view qweb New
message_activity_done message_activity_done ir.ui.view qweb New
message_link_preview_list mail.message.link.preview.list mail.message.link.preview list New
message_notification_limit_email message_notification_limit_email ir.ui.view qweb New
message_notification_out_of_office message_notification_out_of_office ir.ui.view qweb New
message_origin_link message_origin_link ir.ui.view qweb New
message_user_assigned message_user_assigned ir.ui.view qweb New
model_form_view ir.model form Inherits base.view_model_form
model_search_view ir.model search Inherits base.view_model_search
notification_preview notification_preview ir.ui.view qweb New
res_company_view_form res.company.view.form.inherit.mail res.company form Inherits base.view_company_form
res_config_settings_view_form res.config.settings.view.form.inherit.mail res.config.settings form Inherits base_setup.res_config_settings_view_form
res_partner_view_activity res.partner.activity res.partner activity New
res_partner_view_form_inherit_mail res.partner.view.form.inherit.mail res.partner form Inherits base.view_partner_form
res_partner_view_kanban_inherit_mail res.partner.view.kanban.inherit.mail res.partner kanban Inherits base.res_partner_kanban_view
res_partner_view_search_inherit_mail res.partner.view.search.inherit.mail res.partner search Inherits base.view_res_partner_filter
res_partner_view_tree_inherit_mail res.partner.view.list.inherit.mail res.partner list Inherits base.view_partner_tree
res_role_view_form res.role.form res.role form New
res_role_view_search res.role.view.search res.role search New
res_role_view_tree res.role.list res.role list New
res_users_settings_view_form res.users.settings.form res.users.settings form New
res_users_settings_view_tree res.users.settings.list res.users.settings list New
view_document_file_kanban ir.attachment kanban ir.attachment kanban New
view_email_server_form fetchmail.server.form fetchmail.server form New
view_email_server_search fetchmail.server.search fetchmail.server search New
view_email_server_tree fetchmail.server.list fetchmail.server list New
view_email_template_search email.template.search mail.template search New
view_followers_tree mail.followers.list mail.followers list New
view_ice_server_form mail.ice.server.form mail.ice.server form New
view_ice_server_kanban mail.ice.server.kanban mail.ice.server kanban New
view_ice_server_search mail.ice.server.search mail.ice.server search New
view_ice_server_tree mail.ice.server.list mail.ice.server list New
view_mail_form mail.mail.form mail.mail form New
view_mail_message_subtype_form mail.message.subtype.form mail.message.subtype form New
view_mail_search mail.mail.search mail.mail search New
view_mail_subscription_form mail.followers.form mail.followers form New
view_mail_tracking_value_form mail.tracking.value.form mail.tracking.value form New
view_mail_tracking_value_tree mail.tracking.value.list mail.tracking.value list New
view_mail_tree mail.mail.list mail.mail list New
view_message_search mail.message.search mail.message search New
view_message_subtype_tree mail.message.subtype.list mail.message.subtype list New
view_message_tree mail.message.list mail.message list New
view_server_action_form_template ir.actions.server.form ir.actions.server form Inherits base.view_server_action_form
view_users_form_mail res.users.form.mail res.users form Inherits base.view_users_form
view_users_form_simple_modif_mail res.users.preferences.form.mail res.users form Inherits base.view_users_form_simple_modif
HTTP endpoints (65)
Route(s)HandlerAuthTypeMethodsFlags
/mail/attachment/update_thumbnail AttachmentController.mail_attachement_update_thumbnail public jsonrpc POST sudo
/mail/attachment/delete AttachmentController.mail_attachment_delete public jsonrpc POST sudo
/mail/attachment/zip AttachmentController.mail_attachment_get_zip public http POST
/mail/attachment/pdf_first_page/<int:attachment_id> AttachmentController.mail_attachment_pdf_first_page public http GET sudo
/mail/attachment/upload AttachmentController.mail_attachment_upload public http POST sudo
/discuss/channel/update_avatar ChannelController.discuss_channel_avatar_update user jsonrpc POST
/discuss/channel/join ChannelController.discuss_channel_join public jsonrpc POST
/discuss/channel/mark_as_read ChannelController.discuss_channel_mark_as_read public jsonrpc POST
/discuss/channel/members ChannelController.discuss_channel_members public jsonrpc POST
/discuss/channel/messages ChannelController.discuss_channel_messages public jsonrpc POST
/discuss/channel/notify_typing ChannelController.discuss_channel_notify_typing public jsonrpc POST
/discuss/channel/pinned_messages ChannelController.discuss_channel_pins public jsonrpc POST
/discuss/channel/set_new_message_separator ChannelController.discuss_channel_set_new_message_separator public jsonrpc POST
/discuss/channel/sub_channel/create ChannelController.discuss_channel_sub_channel_create public jsonrpc POST
/discuss/channel/sub_channel/fetch ChannelController.discuss_channel_sub_channel_fetch public jsonrpc POST
/discuss/channel/sub_channel/delete ChannelController.discuss_delete_sub_channel user jsonrpc POST sudo
/discuss/channel/attachments ChannelController.load_attachments public jsonrpc POST sudo
/discuss/gif/add_favorite DiscussGifController.add_favorite user jsonrpc ALL
/discuss/gif/categories DiscussGifController.categories user jsonrpc ALL sudo
/discuss/gif/favorites DiscussGifController.get_favorites user jsonrpc ALL
/discuss/gif/remove_favorite DiscussGifController.remove_favorite user jsonrpc ALL
/discuss/gif/search DiscussGifController.search user jsonrpc ALL sudo
/discuss/settings/custom_notifications DiscussSettingsController.discuss_custom_notifications user jsonrpc POST
/discuss/settings/mute DiscussSettingsController.discuss_mute user jsonrpc POST
/mail/message/translate GoogleTranslateController.translate user jsonrpc ALL sudo
/mail/guest/update_name GuestController.mail_guest_update_name public jsonrpc POST sudo
/mail/set_manual_im_status ImStatusController.set_manual_im_status user jsonrpc POST
/mail/link_preview LinkPreviewController.mail_link_preview public jsonrpc POST sudo
/mail/link_preview/hide LinkPreviewController.mail_link_preview_hide public jsonrpc POST sudo
/web_editor/font_to_img/<icon>, /web_editor/font_to_img/<icon>/<color>, /web_editor/font_to_img/<icon>/<color>/<int:size>, /web_editor/font_to_img/<icon>/<color>/<int:width>x<int:height>, /web_editor/font_to_img/<icon>/<color>/<int:size>/<int:alpha>, /web_editor/font_to_img/<icon>/<color>/<int:width>x<int:height>/<int:alpha>, /web_editor/font_to_img/<icon>/<color>/<bg>, /web_editor/font_to_img/<icon>/<color>/<bg>/<int:size>, /web_editor/font_to_img/<icon>/<color>/<bg>/<int:width>x<int:height>, /web_editor/font_to_img/<icon>/<color>/<bg>/<int:width>x<int:height>/<int:alpha>, /mail/font_to_img/<icon>, /mail/font_to_img/<icon>/<color>, /mail/font_to_img/<icon>/<color>/<int:size>, /mail/font_to_img/<icon>/<color>/<int:width>x<int:height>, /mail/font_to_img/<icon>/<color>/<int:size>/<int:alpha>, /mail/font_to_img/<icon>/<color>/<int:width>x<int:height>/<int:alpha>, /mail/font_to_img/<icon>/<color>/<bg>, /mail/font_to_img/<icon>/<color>/<bg>/<int:size>, /mail/font_to_img/<icon>/<color>/<bg>/<int:width>x<int:height>, /mail/font_to_img/<icon>/<color>/<bg>/<int:width>x<int:height>/<int:alpha> MailController.export_icon_to_png none http ALL
/mail/unfollow MailController.mail_action_unfollow public http ALL csrf off sudo
/mail/view MailController.mail_action_view public http ALL sudo
/mail/message/<int:message_id> MailController.mail_thread_message_redirect public http ALL
/mail/history/messages MailboxController.discuss_history_messages user jsonrpc POST
/mail/inbox/messages MailboxController.discuss_inbox_messages user jsonrpc POST sudo
/mail/starred/messages MailboxController.discuss_starred_messages user jsonrpc POST
/mail/message/reaction MessageReactionController.mail_message_reaction public jsonrpc POST sudo
/discuss/channel/<int:channel_id> PublicPageController.discuss_channel public http GET
/chat/<string:create_token>, /chat/<string:create_token>/<string:channel_name> PublicPageController.discuss_channel_chat_from_token public http GET
/chat/<int:channel_id>/<string:invitation_token> PublicPageController.discuss_channel_invitation public http GET sudo
/meet/<string:create_token>, /meet/<string:create_token>/<string:channel_name> PublicPageController.discuss_channel_meet_from_token public http GET
/mail/rtc/audio_worklet_processor_v2 RtcController.audio_worklet_processor public http GET
/mail/rtc/channel/cancel_call_invitation RtcController.channel_call_cancel_invitation public jsonrpc POST sudo
/mail/rtc/channel/join_call RtcController.channel_call_join public jsonrpc POST sudo
/mail/rtc/channel/leave_call RtcController.channel_call_leave public jsonrpc POST sudo
/discuss/channel/ping RtcController.channel_ping public jsonrpc POST sudo
/mail/rtc/channel/upgrade_connection RtcController.channel_upgrade user jsonrpc POST sudo
/mail/rtc/session/notify_call_members RtcController.session_call_notify public jsonrpc POST sudo
/mail/rtc/session/update_and_broadcast RtcController.session_update_and_broadcast public jsonrpc POST sudo
/discuss/search SearchController.search public jsonrpc POST
/mail/message/post ThreadController.mail_message_post public jsonrpc POST sudo
/mail/message/update_content ThreadController.mail_message_update_content public jsonrpc POST sudo
/mail/thread/messages ThreadController.mail_thread_messages user jsonrpc POST
/mail/partner/from_email ThreadController.mail_thread_partner_from_email user jsonrpc POST
/mail/thread/recipients ThreadController.mail_thread_recipients user jsonrpc POST
/mail/thread/recipients/fields ThreadController.mail_thread_recipients_fields user jsonrpc POST
/mail/thread/recipients/get_suggested_recipients ThreadController.mail_thread_recipients_get_suggested_recipients user jsonrpc POST
/mail/thread/subscribe ThreadController.mail_thread_subscribe user jsonrpc POST
/mail/thread/unsubscribe ThreadController.mail_thread_unsubscribe user jsonrpc POST
/mail/read_subscription_data ThreadController.read_subscription_data user jsonrpc POST
/discuss/voice/worklet_processor VoiceController.voice_worklet_processor public http GET
/mail/action WebclientController.mail_action public jsonrpc POST
/mail/data WebclientController.mail_data public jsonrpc POST
(inherited route override) WebsocketControllerPresence.peek_notifications inherited http ALL
/websocket/update_bus_presence WebsocketControllerPresence.update_bus_presence public jsonrpc ALL
Models touched (83)

New fields (0)

No new fields.

Public methods (4)
  • mail_allowed_qweb_expressions(self)
    @api.model
  • mail_get_partner_fields(self)
  • unlink(self)
  • with_user(self, user)
    Override to ensure the guest context is removed as the target user in a with_user should never be considered as being the guest of the outside env.

New fields (0)

No new fields.

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

No public methods.

New fields (5)
  • channel_id Many2one → discuss.channel
    index=True ondelete='cascade' required=True args: 'discuss.channel'
  • duration_hour Float
    compute='_compute_duration_hour'
  • end_dt Datetime
  • start_call_message_id Many2one → mail.message
    index=True args: 'mail.message'
  • start_dt Datetime
    index=True required=True
Public methods (0)

No public methods.

New fields (30)
  • active Boolean
    default=True help='Set active to false to hide the channel without removing it.'
  • avatar_128 Image
    compute='_compute_avatar_128' max_height=128 max_width=128 args: 'Avatar'
  • avatar_cache_key Char
    compute='_compute_avatar_cache_key'
  • call_history_ids One2many → discuss.call.history
    args: 'discuss.call.history', 'channel_id'
  • channel_member_ids One2many → discuss.channel.member
    string='Members' args: 'discuss.channel.member', 'channel_id'
  • channel_name_member_ids One2many → discuss.channel.member
    compute='_compute_channel_name_member_ids' help='Members from which the channel name is computed when the name field is empty.' args: 'discuss.channel.member'
  • channel_partner_ids Many2many → res.partner
    compute='_compute_channel_partner_ids' inverse='_inverse_channel_partner_ids' search='_search_channel_partner_ids' string='Partners' args: 'res.partner'
  • channel_type Selection
    default='channel' help='Chat is private and unique between 2 persons. Group is private among invited persons. Channel can be freely joined (depending on its configuration).' readonly=True required=True string='Channel Type' args: [('chat', 'Chat'), ('channel', 'Channel'), ('group', 'Group')]
  • default_display_mode Selection
    help='Determines how the channel will be displayed by default when opening it from its invitation link. No value means display text (no voice/video).' selection=[('video_full_screen', 'Full screen video')] string='Default Display Mode'
  • description Text
    args: 'Description'
  • from_message_id Many2one → mail.message
    help='The message the channel was created from.' readonly=True args: 'mail.message'
  • group_ids Many2many → res.groups
    help='Members of those groups will automatically added as followers. Note that they will be able to manage their subscription manually if necessary.' string='Auto Subscription' args: 'res.groups'
  • group_public_id Many2one → res.groups
    compute='_compute_group_public_id' readonly=False recursive=True store=True string='Authorized Group' args: 'res.groups'
  • image_128 Image
    max_height=128 max_width=128 args: 'Image'
  • invitation_url Char
    compute='_compute_invitation_url' args: 'Invitation URL'
  • invited_member_ids One2many → discuss.channel.member
    compute='_compute_invited_member_ids' compute_sudo=True args: 'discuss.channel.member'
  • is_editable Boolean
    compute='_compute_is_editable' args: 'Is Editable'
  • is_member Boolean
    compute='_compute_is_member' compute_sudo=True search='_search_is_member' args: 'Is Member'
  • last_interest_dt Datetime
    default=<expr> help='Contains the date and time of the last interesting event that happened in this channel. This updates itself when new message posted.' index=True args: 'Last Interest'
  • member_count Integer
    compute='_compute_member_count' compute_sudo=True string='Member Count'
  • message_count Integer
    compute='_compute_message_count' readonly=True args: '# Messages'
  • name Char
    required=True args: 'Name'
  • parent_channel_id Many2one → discuss.channel
    bypass_search_access=True help='Parent channel' index=True ondelete='cascade' readonly=True args: 'discuss.channel'
  • pinned_message_ids One2many → mail.message
    domain=[('model', '=', 'discuss.channel'), ('pinned_at', '!=', False)] string='Pinned Messages' args: 'mail.message', 'res_id'
  • rtc_session_ids One2many → discuss.channel.rtc.session
    groups='base.group_system' args: 'discuss.channel.rtc.session', 'channel_id'
  • self_member_id Many2one → discuss.channel.member
    compute='_compute_self_member_id' compute_sudo=True args: 'discuss.channel.member'
  • sfu_channel_uuid Char
    groups='base.group_system'
  • sfu_server_url Char
    groups='base.group_system'
  • sub_channel_ids One2many → discuss.channel
    readonly=True string='Sub Channels' args: 'discuss.channel', 'parent_channel_id'
  • uuid Char
    copy=False default=_generate_random_token size=50 args: 'UUID'
Public methods (17)
  • action_unfollow(self)
  • add_members(self, partner_ids=None, guest_ids=None, invite_to_rtc_call=False, post_joined_message=True)
    Adds the given partner_ids and guest_ids as member of self channels.
  • channel_change_description(self, description)
  • channel_fetched(self)
    Broadcast the channel_fetched notification to channel members
  • channel_join(self)
    Shortcut to add the current user as member of self channels. Prefer calling add_members() directly when possible.
  • channel_pin(self, pinned=False)
  • channel_rename(self, name)
  • channel_set_custom_name(self, name)
  • create(self, vals_list)
    @api.model_create_multi
  • execute_command_help(self, **kwargs)
  • execute_command_leave(self, **kwargs)
  • execute_command_who(self, **kwargs)
  • get_mention_suggestions(self, search, limit=8)
    @api.readonly@api.model
    Return 'limit'-first channels' name, channel_type and group_public_id fields such that the name matches a 'search' string. Exclude channels of type chat (DM) and group.
  • invite_by_email(self, emails)
    Send channel invitation emails to a list of email addresses. Existing members' email addresses are ignored. :param emails: List of email addresses to invite. :type emails: list[str]
  • message_post(self, *, message_type='notification', partner_ids=None, **kwargs)
  • set_message_pin(self, message_id, pinned)
    (Un)pin a message on the channel and send a notification to the members. :param message_id: id of the message to be pinned. :param pinned: whether the message should be pinned or unpinned.
  • write(self, vals)

New fields (17)
  • channel_id Many2one → discuss.channel
    bypass_search_access=True ondelete='cascade' required=True args: 'discuss.channel', 'Channel'
  • custom_channel_name Char
    args: 'Custom channel name'
  • custom_notifications Selection
    help='Use default from user settings if not specified. This setting will only be applied to channels.' args: [('all', 'All Messages'), ('mentions', 'Mentions Only'), ('no_notif', 'Nothing')], 'Customized Notifications'
  • fetched_message_id Many2one → mail.message
    index='btree_not_null' string='Last Fetched' args: 'mail.message'
  • guest_id Many2one → mail.guest
    index=True ondelete='cascade' args: 'mail.guest', 'Guest'
  • is_pinned Boolean
    compute='_compute_is_pinned' search='_search_is_pinned' args: 'Is pinned on the interface'
  • is_self Boolean
    compute='_compute_is_self' search='_search_is_self'
  • last_interest_dt Datetime
    default=<expr> help='Contains the date and time of the last interesting event that happened in this channel for this user. This includes: creating, joining, pinning' index=True args: 'Last Interest'
  • last_seen_dt Datetime
    args: 'Last seen date'
  • message_unread_counter Integer
    compute='_compute_message_unread' compute_sudo=True args: 'Unread Messages Counter'
  • mute_until_dt Datetime
    help='If set, the member will not receive notifications from the channel until this date.' args: 'Mute notifications until'
  • new_message_separator Integer
    default=0 help='Message id before which the separator should be displayed' required=True
  • partner_id Many2one → res.partner
    index=True ondelete='cascade' args: 'res.partner', 'Partner'
  • rtc_inviting_session_id Many2one → discuss.channel.rtc.session
    string='Ringing session' args: 'discuss.channel.rtc.session'
  • rtc_session_ids One2many → discuss.channel.rtc.session
    comodel_name='discuss.channel.rtc.session' inverse_name='channel_member_id' string='RTC Sessions'
  • seen_message_id Many2one → mail.message
    index='btree_not_null' string='Last Seen' args: 'mail.message'
  • unpin_dt Datetime
    help='Contains the date and time when the channel was unpinned by the user.' index=True args: 'Unpin date'
Public methods (3)
  • create(self, vals_list)
    @api.model_create_multi
  • unlink(self)
  • write(self, vals)

New fields (9)
  • channel_id Many2one → discuss.channel
    index='btree_not_null' readonly=True related='channel_member_id.channel_id' store=True args: 'discuss.channel'
  • channel_member_id Many2one → discuss.channel.member
    ondelete='cascade' required=True args: 'discuss.channel.member'
  • guest_id Many2one → mail.guest
    related='channel_member_id.guest_id' args: 'mail.guest'
  • is_camera_on Boolean
    string='Is sending user video'
  • is_deaf Boolean
    string='Has disabled incoming sound'
  • is_muted Boolean
    string='Is microphone muted'
  • is_screen_sharing_on Boolean
    string='Is sharing the screen'
  • partner_id Many2one → res.partner
    index=True related='channel_member_id.partner_id' store=True string='Partner' args: 'res.partner'
  • write_date Datetime
    index=True args: 'Last Updated On'
Public methods (3)
  • action_disconnect(self)
  • create(self, vals_list)
    @api.model_create_multi
  • unlink(self)

New fields (1)
  • tenor_gif_id Char
    required=True args: 'GIF id from Tenor'
Public methods (0)

No public methods.

New fields (1)
  • attachment_id Many2one → ir.attachment
    bypass_search_access=True copy=False index=True ondelete='cascade' args: 'ir.attachment'
Public methods (0)

No public methods.

New fields (20)
  • active Boolean
    default=True args: 'Active'
  • attach Boolean
    default=True help='Whether attachments should be downloaded. If not enabled, incoming emails will be stripped of any attachments before being processed' args: 'Keep Attachments'
  • configuration Text
    readonly=True args: 'Configuration'
  • date Datetime
    readonly=True string='Last Fetch Date'
  • error_date Datetime
    help='Date of last failure, reset on success.' readonly=True string='Last Error Date'
  • error_message Text
    readonly=True string='Last Error Message'
  • is_ssl Boolean
    help='Connections are encrypted with SSL/TLS through a dedicated port (default: IMAPS=993, POP3S=995)' args: 'SSL/TLS'
  • message_ids One2many → mail.mail
    readonly=True string='Messages' args: 'mail.mail', 'fetchmail_server_id'
  • name Char
    required=True args: 'Name'
  • object_id Many2one → ir.model
    help='Process each incoming mail as part of a conversation corresponding to this document type. This will create new documents for new conversations, or attach follow-up emails to the existing conversations (documents).' string='Create a New Record' args: 'ir.model'
  • original Boolean
    help='Whether a full original copy of each email should be kept for reference and attached to each processed message. This will usually double the size of your message database.' args: 'Keep Original'
  • password Char
  • port Integer
  • priority Integer
    default=5 help='Defines the order of processing, lower values mean higher priority' readonly=False string='Server Priority'
  • script Char
    default='/mail/static/scripts/odoo-mailgate.py' readonly=True
  • server Char
    help='Hostname or IP of the mail server' readonly=False string='Server Name'
  • server_type Selection
    default='imap' index=True required=True string='Server Type' args: [('imap', 'IMAP Server'), ('pop', 'POP Server'), ('local', 'Local Server')]
  • server_type_info Text
    compute='_compute_server_type_info' args: 'Server Type Info'
  • state Selection
    copy=False default='draft' index=True readonly=True string='Status' args: [('draft', 'Not Confirmed'), ('done', 'Confirmed')]
  • user Char
    readonly=False string='Username'
Public methods (7)
  • button_confirm_login(self)
  • create(self, vals_list)
    @api.model_create_multi
  • fetch_mail(self)
    Action to fetch the mail from the current server.
  • onchange_server_type(self)
    @api.onchange('server_type', 'is_ssl', 'object_id')
  • set_draft(self)
  • unlink(self)
  • write(self, vals)

New fields (1)
  • view_mode Selection
    ondelete={'activity': 'cascade'} selection_add=[('activity', 'Activity')]
Public methods (0)

No public methods.

New fields (23)
  • activity_date_deadline_range Integer
    compute='_compute_activity_info' readonly=False store=True string='Due Date In'
  • activity_date_deadline_range_type Selection
    compute='_compute_activity_info' readonly=False store=True string='Due type' args: [('days', 'Days'), ('weeks', 'Weeks'), ('months', 'Months')]
  • activity_note Html
    compute='_compute_activity_info' readonly=False store=True args: 'Note'
  • activity_summary Char
    compute='_compute_activity_info' readonly=False store=True args: 'Title'
  • activity_type_id Many2one → mail.activity.type
    compute='_compute_activity_info' domain="['|', ('res_model', '=', False), ('res_model', '=', model_name)]" ondelete='restrict' readonly=False store=True string='Activity Type' args: 'mail.activity.type'
  • activity_user_field_name Char
    compute='_compute_activity_user_info' readonly=False store=True args: 'User Field'
  • activity_user_id Many2one → res.users
    compute='_compute_activity_user_info' readonly=False store=True string='Responsible' args: 'res.users'
  • activity_user_type Selection
    compute='_compute_activity_info' help="Use 'Specific User' to always assign the same user on the next activity. Use 'Dynamic User' to specify the field name of the user to choose on the record." readonly=False store=True string='User Type' args: [('specific', 'Specific User'), ('generic', 'Dynamic User (based on record)')]
  • crud_model_id Many2one
    tracking=True
  • evaluation_type Selection
    tracking=True
  • followers_partner_field_name Char
    compute='_compute_followers_info' readonly=False store=True string='Followers Field'
  • followers_type Selection
    compute='_compute_followers_type' help="\n - Specific Followers: select specific contacts to add/remove from record's followers.\n - Dynamic Followers: all contacts of the chosen record's field will be added/removed from followers.\n " readonly=False selection=[('specific', 'Specific Followers'), ('generic', 'Dynamic Followers')] store=True string='Followers Type'
  • link_field_id Many2one
    tracking=True
  • mail_post_autofollow Boolean
    compute='_compute_mail_post_autofollow' readonly=False store=True args: 'Subscribe Recipients'
  • mail_post_method Selection
    compute='_compute_mail_post_method' readonly=False selection=[('email', 'Email'), ('comment', 'Message'), ('note', 'Note')] store=True string='Send Email As'
  • model_id Many2one
    tracking=True
  • name Char
    tracking=True
  • partner_ids Many2many → res.partner
    compute='_compute_followers_info' readonly=False store=True args: 'res.partner'
  • state Selection
    ondelete={'mail_post': 'cascade', 'followers': 'cascade', 'remove_followers': 'cascade', 'next_activity': 'cascade'} selection_add=[('next_activity', 'Create Activity'), ('mail_post', 'Send Email'), ('followers', 'Add Followers'), ('remove_followers', 'Remove Followers'), ('code')] tracking=True
  • template_id Many2one → mail.template
    compute='_compute_template_id' domain="[('model_id', '=', model_id)]" ondelete='set null' readonly=False store=True args: 'mail.template', 'Email Template'
  • update_path Char
    tracking=True
  • value Text
    tracking=True
  • webhook_url Char
    tracking=True
Public methods (0)

No public methods.

New fields (2)
  • has_thumbnail Boolean
    compute='_compute_has_thumbnail'
  • thumbnail Image
Public methods (1)
  • register_as_main_attachment(self, force=True)
    Registers this attachment as the main one of the model it is attached to. :param bool force: if set, the method always updates the existing main attachment otherwise it only sets the main attachment if there is none.

New fields (1)
  • voice_ids One2many → discuss.voice.metadata
    args: 'discuss.voice.metadata', 'attachment_id'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (3)
  • create(self, vals_list)
    @api.model_create_multi
  • set_param(self, key, value)
    @api.model
  • write(self, vals)

New fields (4)
  • interval_number Integer
    tracking=True
  • interval_type Selection
    tracking=True
  • priority Integer
    tracking=True
  • user_id Many2one
    tracking=True
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (1)
  • session_info(self)
    Override to add the current user data (partner or guest) if applicable.

New fields (4)
  • mail_template_ids One2many → mail.template
    comodel_name='mail.template' inverse_name='mail_server_id' readonly=True string='Mail template using this mail server'
  • owner_limit_count Integer
    copy=False args: 'Owner Limit Count'
  • owner_limit_time Datetime
    copy=False args: 'Owner Limit Time'
  • owner_user_id Many2one → res.users
    copy=False args: 'res.users', 'Owner'
Public methods (0)

No public methods.

New fields (3)
  • is_mail_activity Boolean
    default=False string='Has Mail Activity'
  • is_mail_blacklist Boolean
    default=False string='Has Mail Blacklist'
  • is_mail_thread Boolean
    default=False string='Has Mail Thread'
Public methods (2)
  • unlink(self)
    Delete mail data (followers, messages, activities) associated with the models being deleted.
  • write(self, vals)

New fields (1)
  • tracking Integer
    help='If set every modification done to this field is tracked. Value is used to order tracking values.' string='Enable Ordered Tracking'
Public methods (1)
  • unlink(self)
    When unlinking fields populate tracking value table with relevant information. That way if a field is removed (custom tracked, migration or any other reason) we keep the tracking and its relevant information. Do it only when unlinking fields so that we don't duplicate field information for most tracking.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (0)

No public methods.

New fields (1)
  • type Selection
    selection_add=[('activity', 'Activity')]
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 (0)

No public methods.

New fields (25)
  • active Boolean
    default=True
  • activity_category Selection
    readonly=True related='activity_type_id.category'
  • activity_decoration Selection
    readonly=True related='activity_type_id.decoration_type'
  • activity_type_id Many2one → mail.activity.type
    default=_default_activity_type domain="['|', ('res_model', '=', False), ('res_model', '=', res_model)]" ondelete='restrict' string='Activity Type' args: 'mail.activity.type'
  • attachment_ids Many2many → ir.attachment
    bypass_search_access=True string='Attachments' args: 'ir.attachment', 'activity_attachment_rel', 'activity_id', 'attachment_id'
  • automated Boolean
    help='Indicates this activity has been created automatically and not by any user.' readonly=True args: 'Automated activity'
  • can_write Boolean
    compute='_compute_can_write'
  • chaining_type Selection
    readonly=True related='activity_type_id.chaining_type'
  • date_deadline Date
    default=fields.Date.context_today index=True required=True args: 'Due Date'
  • date_done Date
    compute='_compute_date_done' store=True args: 'Done Date'
  • feedback Text
    args: 'Feedback'
  • has_recommended_activities Boolean
    compute='_compute_has_recommended_activities' args: 'Next activities available'
  • icon Char
    readonly=True related='activity_type_id.icon' args: 'Icon'
  • mail_template_ids Many2many
    readonly=True related='activity_type_id.mail_template_ids'
  • note Html
    sanitize_style=True args: 'Note'
  • previous_activity_type_id Many2one → mail.activity.type
    readonly=True string='Previous Activity Type' args: 'mail.activity.type'
  • recommended_activity_type_id Many2one → mail.activity.type
    string='Recommended Activity Type' args: 'mail.activity.type'
  • res_id Many2oneReference
    index=True model_field='res_model' string='Related Document ID'
  • res_model Char
    index=True precompute=True readonly=True related='res_model_id.model' store=True args: 'Related Document Model'
  • res_model_id Many2one → ir.model
    index=True ondelete='cascade' required=False args: 'ir.model', 'Document Model'
  • res_name Char
    compute='_compute_res_name' compute_sudo=True readonly=True store=True args: 'Document Name'
  • state Selection
    compute='_compute_state' args: [('overdue', 'Overdue'), ('today', 'Today'), ('planned', 'Planned'), ('done', 'Done')], 'State'
  • summary Char
    args: 'Summary'
  • user_id Many2one → res.users
    index=True ondelete='cascade' required=False args: 'res.users', 'Assigned to'
  • user_tz Selection
    related='user_id.tz' store=True string='Timezone'
Public methods (18)
  • action_cancel(self)
  • action_close_dialog(self)
    @api.readonly
  • action_done(self)
    Wrapper without feedback because web button add context as parameter, therefore setting context to feedback
  • action_done_redirect_to_other(self)
    Mark activity as done and return action mail.mail_activity_without_access_action. Goal: Unless "keep done" activity is enabled, when marking an activity as done, the activity is deleted and can no more be displayed. To overcome this, we return an action that will launch the list view displaying the activities corresponding to the active_ids from the context (i.e.: the remaining "other activities"). If the right context is not available, we recompute the activities to display.
  • action_done_schedule_next(self)
    Wrapper without feedback because web button add context as parameter, therefore setting context to feedback
  • action_feedback(self, feedback=False, attachment_ids=None)
  • action_feedback_schedule_next(self, feedback=False, attachment_ids=None)
  • action_notify(self)
  • action_open_document(self)
    @api.readonly
    Opens the related record based on the model and ID, or activity if user has no access to the related record.
  • action_reschedule_nextweek(self)
  • action_reschedule_today(self)
  • action_reschedule_tomorrow(self)
  • activity_format(self)
    @api.readonly
  • create(self, vals_list)
    @api.model_create_multi
  • default_get(self, fields)
    @api.model
  • get_activity_data(self, res_model, domain, limit=None, offset=0, fetch_done=False)
    @api.readonly@api.model
    Get aggregate data about records and their activities. The goal is to fetch and compute aggregated data about records and their activities to display them in the activity views and the chatter. For example, the activity view displays it as a table with columns and rows being respectively the activity_types and the activity_res_ids, and the grouped_activities being the table entries with the aggregated data. :param str res_model: model of the records to fetch :param list domain: record search domain :param int limit: maximum number of records to fetch :param int offset: offset of the first record to fetch :param bool fetch_done: determines if "done" activities are integrated in the aggregated data or not. :returns: {'activity_types': dict of activity type info {id: int, name: str, mail_template: list of {id:int, name:str}} 'activity_res_ids': list<int> of record id ordered by closest date (deadline for ongoing activities, and done date for done activities) 'grouped_activities': dict<dict> res_id -> activity_type_id -> aggregated info as: count_by_state dict: mapping state to count (ex.: 'planned': 2) ids list: activity ids for the res_id and activity_type_id reporting_date str: aggregated date of the related activities as oldest deadline of ongoing activities if there are any or most recent date done of completed activities state dict: aggregated state of the related activities user_assigned_ids list: activity responsible id ordered by closest deadline of the related activities attachments_info: dict with information about the attachments {'count': int, 'most_recent_id': int, 'most_recent_name': str} } :rtype: dict
  • unlink(self)
  • write(self, vals)

New fields (10)
  • activity_date_deadline Date
    compute='_compute_activity_date_deadline' compute_sudo=False groups='base.group_user' readonly=True search='_search_activity_date_deadline' store=False args: 'Next Activity Deadline'
  • activity_exception_decoration Selection
    compute='_compute_activity_exception_type' help='Type of the exception activity on record.' search='_search_activity_exception_decoration' args: [('warning', 'Alert'), ('danger', 'Error')]
  • activity_exception_icon Char
    compute='_compute_activity_exception_type' help='Icon to indicate an exception activity.' args: 'Icon'
  • activity_ids One2many → mail.activity
    bypass_search_access=True groups='base.group_user' args: 'mail.activity', 'res_id', 'Activities'
  • activity_state Selection
    compute='_compute_activity_state' groups='base.group_user' help='Status based on activities\nOverdue: Due date is already passed\nToday: Activity date is today\nPlanned: Future activities.' search='_search_activity_state' string='Activity State' args: [('overdue', 'Overdue'), ('today', 'Today'), ('planned', 'Planned')]
  • activity_summary Char
    groups='base.group_user' readonly=False related='activity_ids.summary' search='_search_activity_summary' args: 'Next Activity Summary'
  • activity_type_icon Char
    related='activity_ids.icon' args: 'Activity Type Icon'
  • activity_type_id Many2one → mail.activity.type
    groups='base.group_user' readonly=False related='activity_ids.activity_type_id' search='_search_activity_type_id' args: 'mail.activity.type', 'Next Activity Type'
  • activity_user_id Many2one → res.users
    compute='_compute_activity_user_id' groups='base.group_user' readonly=True search='_search_activity_user_id' args: 'res.users', 'Responsible User'
  • my_activity_date_deadline Date
    compute='_compute_my_activity_date_deadline' compute_sudo=False groups='base.group_user' readonly=True search='_search_my_activity_date_deadline' args: 'My Activity Deadline'
Public methods (9)
  • action_reschedule_my_next_nextweek(self)
  • action_reschedule_my_next_today(self)
  • action_reschedule_my_next_tomorrow(self)
  • activity_feedback(self, act_type_xmlids, user_id=None, feedback=None, attachment_ids=None, only_automated=True)
    Set activities as done, limiting to some activity types and optionally to a given user.
  • activity_reschedule(self, act_type_xmlids, user_id=None, date_deadline=None, new_user_id=None, only_automated=True)
    Reschedule some automated activities. Activities to reschedule are selected based on type xml ids and optionally by user. Purpose is to be able to * update the deadline to date_deadline; * update the responsible to new_user_id;
  • activity_schedule(self, act_type_xmlid='', date_deadline=None, summary='', note='', **act_values)
    Schedule an activity on each record of the current record set. This method allow to provide as parameter act_type_xmlid. This is an xml_id of activity type instead of directly giving an activity_type_id. It is useful to avoid having various "env.ref" in the code and allow to let the mixin handle access rights. Note that unless specified otherwise in act_values, the activities created will have their "automated" field set to True. :param date_deadline: the day the activity must be scheduled on the timezone of the user must be considered to set the correct deadline
  • activity_search(self, act_type_xmlids='', user_id=None, additional_domain=None, only_automated=True)
    Search automated activities on current record set, given a list of activity types xml IDs. It is useful when dealing with specific types involved in automatic activities management. :param act_type_xmlids: list of activity types xml IDs :param user_id: if set, restrict to activities of that user_id; :param additional_domain: if set, filter on that domain; :param only_automated: if unset, search for all activities, not only automated ones;
  • activity_send_mail(self, template_id)
    Automatically send an email based on the given mail.template, given its ID.
  • activity_unlink(self, act_type_xmlids, user_id=None, only_automated=True)
    Unlink activities, limiting to some activity types and optionally to a given user.

New fields (8)
  • active Boolean
    default=True
  • company_id Many2one → res.company
    default=<expr> args: 'res.company'
  • has_user_on_demand Boolean
    compute='_compute_has_user_on_demand' args: 'Has on demand responsible'
  • name Char
    required=True args: 'Name'
  • res_model Selection
    help='Specify a model if the activity should be specific to a model and not available when managing activities for other models.' required=True selection=_get_model_selection string='Model'
  • res_model_id Many2one → ir.model
    compute='_compute_res_model_id' compute_sudo=True ondelete='cascade' precompute=True readonly=False required=True store=True string='Applies to' args: 'ir.model'
  • steps_count Integer
    compute='_compute_steps_count'
  • template_ids One2many → mail.activity.plan.template
    copy=True string='Activities' args: 'mail.activity.plan.template', 'plan_id'
Public methods (1)
  • copy_data(self, default=None)

New fields (14)
  • activity_type_id Many2one → mail.activity.type
    default=<expr> domain="['|', ('res_model', '=', False), '&', ('res_model', '!=', False), ('res_model', '=', parent.res_model)]" ondelete='restrict' required=True args: 'mail.activity.type', 'Activity Type'
  • company_id Many2one
    related='plan_id.company_id'
  • delay_count Integer
    default=0 help='Number of days/week/month before executing the action after or before the scheduled plan date.' args: 'Interval'
  • delay_from Selection
    default='before_plan_date' required=True string='Trigger' args: [('before_plan_date', 'Before Plan Date'), ('after_plan_date', 'After Plan Date')]
  • delay_unit Selection
    default='days' help='Unit of delay' required=True string='Delay units' args: [('days', 'days'), ('weeks', 'weeks'), ('months', 'months')]
  • icon Char
    readonly=True related='activity_type_id.icon' args: 'Icon'
  • next_activity_ids Many2many → mail.activity.type
    compute='_compute_next_activity_ids' readonly=False store=True string='Next Activities' args: 'mail.activity.type'
  • note Html
    compute='_compute_note' readonly=False store=True args: 'Note'
  • plan_id Many2one → mail.activity.plan
    index=True ondelete='cascade' required=True string='Plan' args: 'mail.activity.plan'
  • res_model Selection
    related='plan_id.res_model'
  • responsible_id Many2one → res.users
    check_company=True compute='_compute_responsible_id' readonly=False store=True args: 'res.users', 'Assigned to'
  • responsible_type Selection
    compute='_compute_responsible_type' default='on_demand' readonly=False required=True store=True string='Assignment' args: [('on_demand', 'Ask at launch'), ('other', 'Default user')]
  • sequence Integer
    default=10
  • summary Char
    compute='_compute_summary' readonly=False store=True args: 'Summary'
Public methods (0)

No public methods.

New fields (22)
  • activity_category Selection
    readonly=True related='activity_type_id.category'
  • activity_type_id Many2one → mail.activity.type
    compute='_compute_activity_type_id' domain="['|', ('res_model', '=', False), ('res_model', '=', res_model)]" ondelete='set null' readonly=False store=True string='Activity Type' args: 'mail.activity.type'
  • activity_user_id Many2one → res.users
    compute='_compute_activity_user_id' readonly=False store=True args: 'res.users', 'Assigned to'
  • chaining_type Selection
    readonly=True related='activity_type_id.chaining_type'
  • company_id Many2one → res.company
    compute='_compute_company_id' required=False args: 'res.company', 'Company'
  • date_deadline Date
    compute='_compute_date_deadline' readonly=False store=True args: 'Due Date'
  • error Html
    compute='_compute_error'
  • has_error Boolean
    compute='_compute_error'
  • has_warning Boolean
    compute='_compute_error'
  • is_batch_mode Boolean
    compute='_compute_is_batch_mode' args: 'Use in batch'
  • note Html
    compute='_compute_note' readonly=False sanitize_style=True store=True args: 'Note'
  • plan_available_ids Many2many → mail.activity.plan
    compute='_compute_plan_available_ids' compute_sudo=True store=True args: 'mail.activity.plan'
  • plan_date Date
    compute='_compute_plan_date' readonly=False store=True args: 'Plan Date'
  • plan_has_user_on_demand Boolean
    related='plan_id.has_user_on_demand'
  • plan_id Many2one → mail.activity.plan
    compute='_compute_plan_id' domain="[('id', 'in', plan_available_ids)]" readonly=False store=True args: 'mail.activity.plan'
  • plan_on_demand_user_id Many2one → res.users
    default=<expr> help='Choose assignation for activities with on demand assignation.' args: 'res.users', 'Assigned To'
  • plan_schedule_line_ids One2many → mail.activity.schedule.line
    compute='_compute_plan_schedule_line_ids' string='Schedule Lines' args: 'mail.activity.schedule.line', 'activity_schedule_id'
  • res_ids Text
    compute='_compute_res_ids' precompute=True readonly=False store=True args: 'Document IDs'
  • res_model Char
    readonly=False required=False args: 'Model'
  • res_model_id Many2one → ir.model
    compute='_compute_res_model_id' compute_sudo=True ondelete='cascade' precompute=True readonly=False required=False store=True string='Applies to' args: 'ir.model'
  • summary Char
    compute='_compute_summary' readonly=False store=True args: 'Summary'
  • warning Html
    compute='_compute_error'
Public methods (5)
  • action_schedule_activities(self)
  • action_schedule_activities_done(self)
  • action_schedule_plan(self)
  • default_get(self, fields)
    @api.model
  • get_model_options(self)
    @api.readonly@api.model
    Return a list of valid models for a user to define an activity on.

New fields (4)
  • activity_schedule_id Many2one → mail.activity.schedule
    ondelete='cascade' required=True string='Activity Schedule' args: 'mail.activity.schedule'
  • line_date_deadline Date
    args: 'Date Deadline'
  • line_description Char
    args: 'Line Description'
  • responsible_user_id Many2one → res.users
    string='Responsible User' args: 'res.users'
Public methods (0)

No public methods.

New fields (22)
  • active Boolean
    default=True
  • category Selection
    default='default' help='Actions may trigger specific behavior like opening calendar view or automatically mark as done when a document is uploaded' string='Action' args: [('default', 'None'), ('upload_file', 'Upload Document'), ('phonecall', 'Phonecall')]
  • chaining_type Selection
    default='suggest' required=True string='Chaining Type' args: [('suggest', 'Suggest Next Activity'), ('trigger', 'Trigger Next Activity')]
  • create_uid Many2one → res.users
    index=True args: 'res.users'
  • decoration_type Selection
    help='Change the background color of the related activities of this type.' string='Decoration Type' args: [('warning', 'Alert'), ('danger', 'Error')]
  • default_note Html
    string='Default Note' translate=True
  • default_user_id Many2one → res.users
    string='Default User' args: 'res.users'
  • delay_count Integer
    default=0 help='Number of days/week/month before executing the action. It allows to plan the action deadline.' args: 'Schedule'
  • delay_from Selection
    default='previous_activity' help='Type of delay' required=True string='Delay Type' args: [('current_date', 'after previous activity completion date'), ('previous_activity', 'after previous activity deadline')]
  • delay_label Char
    compute='_compute_delay_label'
  • delay_unit Selection
    default='days' help='Unit of delay' required=True string='Delay units' args: [('days', 'days'), ('weeks', 'weeks'), ('months', 'months')]
  • icon Char
    help='Font awesome icon e.g. fa-tasks' args: 'Icon'
  • initial_res_model Selection
    compute='_compute_initial_res_model' help='Technical field to keep track of the model at the start of editing to support UX related behaviour' selection=_get_model_selection store=False string='Initial model'
  • mail_template_ids Many2many → mail.template
    string='Email templates' args: 'mail.template'
  • name Char
    required=True translate=True args: 'Name'
  • previous_type_ids Many2many → mail.activity.type
    domain="['|', ('res_model', '=', False), ('res_model', '=', res_model)]" string='Preceding Activities' args: 'mail.activity.type', 'mail_activity_rel', 'recommended_id', 'activity_id'
  • res_model Selection
    help='Specify a model if the activity should be specific to a model and not available when managing activities for other models.' selection=_get_model_selection string='Model'
  • res_model_change Boolean
    default=False store=False string='Model has change'
  • sequence Integer
    default=10 args: 'Sequence'
  • suggested_next_type_ids Many2many → mail.activity.type
    compute='_compute_suggested_next_type_ids' domain="['|', ('res_model', '=', False), ('res_model', '=', res_model)]" help='Suggest these activities once the current one is marked as done.' inverse='_inverse_suggested_next_type_ids' readonly=False store=True string='Suggest' args: 'mail.activity.type', 'mail_activity_rel', 'activity_id', 'recommended_id'
  • summary Char
    translate=True args: 'Default Summary'
  • triggered_next_type_id Many2one → mail.activity.type
    compute='_compute_triggered_next_type_id' domain="['|', ('res_model', '=', False), ('res_model', '=', res_model)]" help='Automatically schedule this activity once the current one is marked as done.' inverse='_inverse_triggered_next_type_id' ondelete='restrict' readonly=False store=True string='Trigger' args: 'mail.activity.type'
Public methods (3)
  • action_archive(self)
  • unlink(self)
    When removing an activity type, put activities into a Todo.
  • write(self, vals)

New fields (13)
  • alias_bounced_content Html
    help='If set, this content will automatically be sent out to unauthorized users instead of the default message.' translate=True args: 'Custom Bounced Message'
  • alias_contact Selection
    default='everyone' help='Policy to post a message on the document using the mailgateway.\n- everyone: everyone can post\n- partners: only authenticated partners\n- followers: only followers of the related document or members of following channels\n' required=True string='Alias Contact Security' args: [('everyone', 'Everyone'), ('partners', 'Authenticated Partners'), ('followers', 'Followers only')]
  • alias_defaults Text
    default='{}' help='A Python dictionary that will be evaluated to provide default values when creating new records for this alias.' required=True args: 'Default Values'
  • alias_domain Char
    related='alias_domain_id.name' args: 'Alias domain name'
  • alias_domain_id Many2one → mail.alias.domain
    default=<expr> ondelete='restrict' string='Alias Domain' args: 'mail.alias.domain'
  • alias_force_thread_id Integer
    help='Optional ID of a thread (record) to which all incoming messages will be attached, even if they did not reply to it. If set, this will disable the creation of new records completely.' args: 'Record Thread ID'
  • alias_full_name Char
    compute='_compute_alias_full_name' index='btree_not_null' store=True args: 'Alias Email'
  • alias_incoming_local Boolean
    default=False args: 'Local-part based incoming detection'
  • alias_model_id Many2one → ir.model
    domain="[('field_id.name', '=', 'message_ids')]" help='The model (Odoo Document Kind) to which this alias corresponds. Any incoming email that does not reply to an existing record will cause the creation of a new record of this model (e.g. a Project Task)' ondelete='cascade' required=True args: 'ir.model', 'Aliased Model'
  • alias_name Char
    copy=False help="The name of the email alias, e.g. 'jobs' if you want to catch emails for <jobs@example.odoo.com>" args: 'Alias Name'
  • alias_parent_model_id Many2one → ir.model
    help='Parent model holding the alias. The model holding the alias reference is not necessarily the model given by alias_model_id (example: project (parent_model) and task (model))' args: 'ir.model', 'Parent Model'
  • alias_parent_thread_id Integer
    help='ID of the parent record holding the alias (example: project holding the task creation alias)' args: 'Parent Record Thread ID'
  • alias_status Selection
    compute='_compute_alias_status' help='Alias status assessed on the last message received.' store=True args: [('not_tested', 'Not Tested'), ('valid', 'Valid'), ('invalid', 'Invalid')]
Public methods (4)
  • create(self, vals_list)
    @api.model_create_multi
    Creates mail.alias records according to the values provided in ``vals`` but sanitize 'alias_name' by replacing certain unsafe characters; set default alias domain if not given. :raise UserError: if given (alias_name, alias_domain_id) already exists or if there are duplicates in given vals_list;
  • open_document(self)
  • open_parent_document(self)
  • write(self, vals)
    Raise UserError with a meaningful message instead of letting the uniqueness constraint raise an SQL error. To check uniqueness we have to rebuild pairs of names / domains to validate, taking into account that a void alias_domain_id is acceptable (but also raises for uniqueness).

New fields (9)
  • bounce_alias Char
    default='bounce' help="Local-part of email used for Return-Path used when emails bounce e.g. 'bounce' in 'bounce@example.com'" required=True args: 'Bounce Alias'
  • bounce_email Char
    compute='_compute_bounce_email' args: 'Bounce Email'
  • catchall_alias Char
    default='catchall' help="Local-part of email used for Reply-To to catch answers e.g. 'catchall' in 'catchall@example.com'" required=True args: 'Catchall Alias'
  • catchall_email Char
    compute='_compute_catchall_email' args: 'Catchall Email'
  • company_ids One2many → res.company
    help='Companies using this domain as default for sending mails' string='Companies' args: 'res.company', 'alias_domain_id'
  • default_from Char
    default='notifications' help="Default from when it does not match outgoing server filters. Can be either a local-part e.g. 'notifications' either a complete email address e.g. 'notifications@example.com' to override all outgoing emails." args: 'Default From Alias'
  • default_from_email Char
    compute='_compute_default_from_email' args: 'Default From'
  • name Char
    help="Email domain e.g. 'example.com' in 'odoo@example.com'" required=True args: 'Name'
  • sequence Integer
    default=10
Public methods (2)
  • create(self, vals_list)
    @api.model_create_multi
    Sanitize bounce_alias / catchall_alias / default_from
  • write(self, vals)
    Sanitize name / bounce_alias / catchall_alias / default_from

New fields (3)
  • alias_defaults Text
    inherited=True
  • alias_id Many2one
    required=True
  • alias_name Char
    inherited=True
Public methods (0)

No public methods.

New fields (6)
  • alias_defaults Text
    related='alias_id.alias_defaults'
  • alias_domain Char
    related='alias_id.alias_domain' args: 'Alias Domain Name'
  • alias_domain_id Many2one → mail.alias.domain
    readonly=False related='alias_id.alias_domain_id' string='Alias Domain' args: 'mail.alias.domain'
  • alias_email Char
    compute='_compute_alias_email' search='_search_alias_email' args: 'Email Alias'
  • alias_id Many2one → mail.alias
    copy=False ondelete='restrict' required=False string='Alias' args: 'mail.alias'
  • alias_name Char
    readonly=False related='alias_id.alias_name'
Public methods (4)
  • copy_data(self, default=None)
  • create(self, vals_list)
    @api.model_create_multi
    Create aliases using sudo if an alias is required, notably if its name is given.
  • unlink(self)
    Delete the given records, and cascade-delete their corresponding alias.
  • write(self, vals)
    Split writable fields of mail.alias and other fields alias fields will write with sudo and the other normally. Also handle alias_domain_id update. If alias does not exist and we try to set a name, create the alias automatically.

New fields (2)
  • active Boolean
    default=True tracking=2
  • email Char
    help='This field is case insensitive.' index='trigram' required=True string='Email Address' tracking=1
Public methods (4)
  • action_add(self)
  • create(self, vals_list)
    @api.model_create_multi
  • mail_action_blacklist_remove(self)
  • write(self, vals)

New fields (2)
  • email Char
    name='Email' readonly=True required=True
  • reason Char
    name='Reason'
Public methods (1)
  • action_unblacklist_apply(self)

New fields (6)
  • group_ids Many2many → res.groups
    domain=<expr> string='Authorized Groups' args: 'res.groups'
  • is_editable Boolean
    compute='_compute_is_editable' string='Determines if the canned response can be edited by the current user'
  • is_shared Boolean
    compute='_compute_is_shared' store=True string='Determines if the canned_response is currently shared with other users'
  • last_used Datetime
    help='Last time this canned_response was used' args: 'Last Used'
  • source Char
    help="Canned response that will automatically be substituted with longer content in your messages. Type '::' followed by the name of your shortcut (e.g. ::hello) to use in your messages." index='trigram' required=True args: 'Shortcut'
  • substitution Text
    help='Content that will automatically replace the shortcut of your choosing. This content can still be adapted before sending your message.' required=True args: 'Substitution'
Public methods (3)
  • create(self, vals_list)
    @api.model_create_multi
  • unlink(self)
  • write(self, vals)

New fields (39)
  • attachment_ids Many2many → ir.attachment
    bypass_search_access=True compute='_compute_attachment_ids' readonly=False store=True string='Attachments' args: 'ir.attachment', 'mail_compose_message_ir_attachments_rel', 'wizard_id', 'attachment_id'
  • author_id Many2one → res.partner
    compute='_compute_authorship' compute_sudo=False help='Author of the message. If not set, email_from may hold an email address that did not match any partner.' readonly=False store=True string='Author' args: 'res.partner'
  • auto_delete Boolean
    compute='_compute_auto_delete' compute_sudo=False help="This option permanently removes any track of email after it's been sent, including from the Technical menu in the Settings, in order to preserve storage space of your Odoo database." readonly=False store=True args: 'Delete Emails'
  • auto_delete_keep_log Boolean
    compute='_compute_auto_delete_keep_log' help='Keep a copy of the email content if emails are removed (mass mailing only)' readonly=False store=True args: 'Keep Message Copy'
  • body Html
    compute='_compute_body' readonly=False render_engine='qweb' render_options={'post_process': True} sanitize_style=True store=True args: 'Contents'
  • composition_batch Boolean
    compute='_compute_composition_batch' args: 'Batch composition'
  • composition_comment_option Selection
    string='Comment Options' args: [('reply_all', 'Reply-All'), ('forward', 'Forward')]
  • composition_mode Selection
    default='comment' selection=[('comment', 'Post on a document'), ('mass_mail', 'Email Mass Mailing')] string='Composition mode'
  • email_add_signature Boolean
    compute='_compute_email_add_signature' readonly=False store=True args: 'Add signature'
  • email_from Char
    compute='_compute_authorship' compute_sudo=False help='Email address of the sender. This field is set when no matching partner is found and replaces the author_id field in the chatter.' readonly=False store=True args: 'From'
  • email_layout_xmlid Char
    compute='_compute_email_layout_xmlid' compute_sudo=False copy=False readonly=False store=True args: 'Email Notification Layout'
  • force_send Boolean
    compute='_compute_force_send' readonly=False store=True args: 'Send mailing or notifications directly'
  • mail_activity_type_id Many2one → mail.activity.type
    ondelete='set null' args: 'mail.activity.type', 'Mail Activity Type'
  • mail_server_id Many2one → ir.mail_server
    compute='_compute_mail_server_id' compute_sudo=False readonly=False store=True string='Outgoing mail server' args: 'ir.mail_server'
  • message_type Selection
    default='comment' help='Message type: email for email message, notification for system message, comment for other messages such as user replies' required=True args: [('auto_comment', 'Automated Targeted Notification'), ('comment', 'Comment'), ('notification', 'System notification')], 'Type'
  • model Char
    compute='_compute_model' readonly=False store=True args: 'Related Document Model'
  • model_is_thread Boolean
    compute='_compute_model_is_thread' args: 'Thread-Enabled'
  • notified_bcc_contains_share Boolean
    compute='_compute_notified_bcc_contains_share' args: 'Is an external partner follower of the document?'
  • notify_author Boolean
    compute='_compute_notify_author' readonly=False store=True
  • notify_author_mention Boolean
    compute='_compute_notify_author_mention' readonly=False store=True
  • notify_skip_followers Boolean
    compute='_compute_notify_skip_followers' readonly=False store=True
  • parent_id Many2one → mail.message
    ondelete='set null' args: 'mail.message', 'Parent Message'
  • partner_ids Many2many → res.partner
    compute='_compute_partner_ids' readonly=False store=True args: 'res.partner', 'mail_compose_message_res_partner_rel', 'wizard_id', 'partner_id', 'Additional Contacts'
  • partner_ids_all_have_email Boolean
    compute='_compute_partner_ids_all_have_email'
  • record_alias_domain_id Many2one → mail.alias.domain
    compute='_compute_record_environment' readonly=False store=True args: 'mail.alias.domain', 'Alias Domain'
  • record_company_id Many2one → res.company
    compute='_compute_record_environment' readonly=False store=True args: 'res.company', 'Company'
  • reply_to Char
    compute='_compute_reply_to' compute_sudo=False help='Reply email address. Setting the reply_to bypasses the automatic thread creation.' readonly=False store=True args: 'Reply To'
  • reply_to_force_new Boolean
    compute='_compute_reply_to_force_new' help='Manage answers as new incoming emails instead of replies going to the same thread.' readonly=False store=True string='Considers answers as new thread'
  • reply_to_mode Selection
    compute='_compute_reply_to_mode' help='Original Discussion: Answers go in the original document discussion thread. \n Another Email Address: Answers go to the email address mentioned in the tracking message-id instead of original document discussion thread. \n This has an impact on the generated message-id.' inverse='_inverse_reply_to_mode' string='Replies' args: [('update', 'Store email and replies in the chatter of each record'), ('new', 'Collect replies on a specific email address')]
  • res_domain Text
    args: 'Active domain'
  • res_domain_user_id Many2one → res.users
    help='Used as context used to evaluate composer domain' string='Responsible' args: 'res.users'
  • res_ids Text
    compute='_compute_res_ids' readonly=False store=True args: 'Related Document IDs'
  • scheduled_date Char
    compute='_compute_scheduled_date' compute_sudo=False help='In comment mode: if set, postpone notifications sending. In mass mail mode: if sent, send emails after that date. This date is considered as being in UTC timezone.' readonly=False store=True args: 'Scheduled Date'
  • subject Char
    compute='_compute_subject' readonly=False store=True args: 'Subject'
  • subtype_id Many2one → mail.message.subtype
    compute='_compute_subtype_id' ondelete='set null' readonly=False store=True args: 'mail.message.subtype', 'Subtype'
  • subtype_is_log Boolean
    compute='_compute_subtype_is_log' args: 'Is a log'
  • template_id Many2one → mail.template
    domain="[('model', '=', model), '|', ('user_id','=', False), ('user_id', '=', uid)]" args: 'mail.template', 'Use template'
  • template_name Char
    args: 'Template Name'
  • use_exclusion_list Boolean
    copy=False default=True help='Prevent sending messages to blacklisted contacts. Disable only when absolutely necessary.' args: 'Use Exclusion List'
Public methods (6)
  • action_schedule_message(self)
  • action_send_mail(self)
    Used for action button that do not accept arguments.
  • cancel_save_template(self)
    Restore old subject when canceling the 'save as template' action as it was erased to let user give a more custom input.
  • create_mail_template(self)
    creates a mail template with the current mail composer's fields
  • default_get(self, fields)
    @api.model
    Handle composition mode and contextual computation, until moving to computed fields. Support active_model / active_id(s) as valid default values, as this comes from standard web client usage. Note that supporting active_ids through composer is still done, as we may have to give a huge list of IDs that won't fit into res_ids field.
  • open_template_creation_wizard(self)
    hit save as template button: opens a wizard that prompts for the template's subject. `create_mail_template` is called when saving the new wizard.

New fields (7)
  • body Html
    compute='_compute_body' compute_sudo=False readonly=False render_engine='qweb' render_options={'post_process': True} sanitize='email_outgoing' store=True args: 'Contents'
  • body_has_template_value Boolean
    compute='_compute_body_has_template_value' args: 'Body content is the same as the template'
  • can_edit_body Boolean
    compute='_compute_can_edit_body' args: 'Can Edit Body'
  • is_mail_template_editor Boolean
    compute='_compute_is_mail_template_editor' args: 'Is Editor'
  • lang Char
    compute='_compute_lang' compute_sudo=False precompute=True readonly=False store=True
  • subject Char
    compute='_compute_subject' compute_sudo=False readonly=False store=True args: 'Subject'
  • template_id Many2one → mail.template
    domain="[('model', '=', render_model)]" args: 'mail.template', 'Mail Template'
Public methods (0)

No public methods.

New fields (7)
  • email Char
    related='partner_id.email' args: 'Email'
  • is_active Boolean
    related='partner_id.active' args: 'Is Active'
  • name Char
    related='partner_id.name' args: 'Name'
  • partner_id Many2one → res.partner
    index=True ondelete='cascade' required=True string='Related Partner' args: 'res.partner'
  • res_id Many2oneReference
    help='Id of the followed resource' index=True model_field='res_model' args: 'Related Document ID'
  • res_model Char
    index=True required=True args: 'Related Document Model Name'
  • subtype_ids Many2many → mail.message.subtype
    help="Message subtypes followed, meaning subtypes that will be pushed onto the user's Wall." string='Subtype' args: 'mail.message.subtype'
Public methods (3)
  • create(self, vals_list)
    @api.model_create_multi
  • unlink(self)
  • write(self, vals)

New fields (6)
  • message Html
    args: 'Message'
  • notify Boolean
    default=False args: 'Notify Recipients'
  • operation Selection
    default='add' required=True string='Operation' args: [('add', 'Add'), ('remove', 'Remove')]
  • partner_ids Many2many → res.partner
    required=True string='Followers' args: 'res.partner'
  • res_ids Char
    help='Ids of the followed resources' args: 'Related Document IDs'
  • res_model Char
    help='Model of the followed resource' required=True args: 'Related Document Model'
Public methods (1)
  • edit_followers(self)

New fields (2)
  • email Char
    required=True args: 'Email Address'
  • email_normalized Char
    compute='_compute_email_normalized' index=True store=True string='Normalized Email'
Public methods (1)
  • get_empty_list_help(self, help_message)
    @api.model

New fields (10)
  • access_token Char
    copy=False default=<expr> groups='base.group_system' readonly=True required=True string='Access Token'
  • channel_ids Many2many → discuss.channel
    column1='guest_id' column2='channel_id' comodel_name='discuss.channel' copy=False relation='discuss_channel_member' string='Channels'
  • country_id Many2one → res.country
    comodel_name='res.country' string='Country'
  • email Char
  • im_status Char
    compute='_compute_im_status' compute_sudo=True args: 'IM Status'
  • lang Selection
    selection=_lang_get string='Language'
  • name Char
    required=True string='Name'
  • offline_since Datetime
    compute='_compute_im_status' compute_sudo=True args: 'Offline since'
  • presence_ids One2many → mail.presence
    groups='base.group_system' args: 'mail.presence', 'guest_id'
  • timezone Selection
    selection=_tz_get string='Timezone'
Public methods (0)

No public methods.

New fields (4)
  • credential Char
  • server_type Selection
    default='stun' required=True string='Type' args: [('stun', 'stun:'), ('turn', 'turn:')]
  • uri Char
    required=True args: 'URI'
  • username Char
Public methods (0)

No public methods.

New fields (10)
  • create_date Datetime
    index=True
  • image_mimetype Char
    args: 'Image MIME type'
  • message_link_preview_ids One2many → mail.message.link.preview
    groups='base.group_erp_manager' args: 'mail.message.link.preview', 'link_preview_id'
  • og_description Text
    args: 'Description'
  • og_image Char
    args: 'Image'
  • og_mimetype Char
    args: 'MIME type'
  • og_site_name Char
    args: 'Site name'
  • og_title Char
    args: 'Title'
  • og_type Char
    args: 'Type'
  • source_url Char
    required=True args: 'URL'
Public methods (0)

No public methods.

New fields (19)
  • auto_delete Boolean
    help="This option permanently removes any track of email after it's been sent, including from the Technical menu in the Settings, in order to preserve storage space of your Odoo database." args: 'Auto Delete'
  • body_content Html
    compute='_compute_body_content' sanitize=True search='_search_body_content' args: 'Rich-text Contents'
  • body_html Text
    help='Rich-text/HTML message' args: 'Text Contents'
  • email_cc Char
    help='Carbon copy message recipients' args: 'Cc'
  • email_to Text
    help='Message recipients (emails)' args: 'To'
  • failure_reason Text
    copy=False help='Failure reason. This is usually the exception thrown by the email server, stored to ease the debugging of mailing issues.' readonly=True args: 'Failure Reason'
  • failure_type Selection
    selection=[('unknown', 'Unknown error'), ('mail_spam', 'Detected As Spam'), ('mail_email_invalid', 'Invalid email address'), ('mail_email_missing', 'Missing email'), ('mail_from_invalid', 'Invalid from address'), ('mail_from_missing', 'Missing from address'), ('mail_smtp', 'Connection failed (outgoing mail server problem)'), ('mail_bl', 'Blacklisted Address'), ('mail_optout', 'Opted Out'), ('mail_dup', 'Duplicated Email')] string='Failure type'
  • fetchmail_server_id Many2one → fetchmail.server
    index='btree_not_null' readonly=True args: 'fetchmail.server', 'Inbound Mail Server'
  • headers Text
    copy=False args: 'Headers'
  • is_notification Boolean
    help='Mail has been created to notify people of an existing mail.message' args: 'Notification Email'
  • mail_message_id Many2one → mail.message
    bypass_search_access=True index=True ondelete='cascade' required=True args: 'mail.message', 'Message'
  • mail_message_id_int Integer
    compute='_compute_mail_message_id_int' compute_sudo=True
  • message_type Selection
    default='email_outgoing' inherited=True related='mail_message_id.message_type'
  • recipient_ids Many2many → res.partner
    context={'active_test': False} string='To (Partners)' args: 'res.partner'
  • references Text
    help='Message references, such as identifiers of previous messages' readonly=True args: 'References'
  • restricted_attachment_count Integer
    compute='_compute_restricted_attachments' args: 'Restricted attachments'
  • scheduled_date Datetime
    help='If set, the queue manager will send the email after the date. If not set, the email will be send as soon as possible. Unless a timezone is specified, it is considered as being in UTC timezone.' args: 'Scheduled Send Date'
  • state Selection
    copy=False default='outgoing' readonly=True args: [('outgoing', 'Outgoing'), ('sent', 'Sent'), ('received', 'Received'), ('exception', 'Delivery Failed'), ('cancel', 'Cancelled')], 'Status'
  • unrestricted_attachment_ids Many2many → ir.attachment
    compute='_compute_restricted_attachments' inverse='_inverse_unrestricted_attachment_ids' string='Unrestricted Attachments' args: 'ir.attachment'
Public methods (12)
  • action_open_document(self)
    Opens the related record based on the model and ID
  • action_retry(self)
  • action_send_and_close(self)
    An action sending the selected mail and redirecting to mail.mail list view.
  • cancel(self)
  • create(self, vals_list)
    @api.model_create_multi
  • default_get(self, fields)
    @api.model
  • mark_outgoing(self)
  • process_email_queue(self, email_ids=(), batch_size=1000)
    @api.model
    Send immediately queued messages, committing after each message is sent - this is not transactional and should not be called during another transaction! A maximum of 1K MailMail (configurable using 'mail.mail.queue.batch.size' optional ICP) are fetched in order to keep time under control. :param list email_ids: optional list of emails ids to send. If given only scheduled and outgoing emails within this ids list are sent;
  • send(self, auto_commit=False, raise_exception=False, post_send_callback=None)
    Sends the selected emails immediately, ignoring their current state (mails that have already been sent should not be passed unless they should actually be re-sent). Emails successfully delivered are marked as 'sent', and those that fail to be deliver are marked as 'exception', and the corresponding error mail is output in the server logs. :param bool auto_commit: whether to force a commit of the mail status after sending each mail (meant only for scheduler processing); should never be True during normal transactions (default: False) :param bool raise_exception: whether to raise an exception if the email sending process has failed :param post_send_callback: an optional function, called as ``post_send_callback(ids, force=False)``, with the mail ids that have been sent; calls with redundant ids are possible :return: True
  • send_after_commit(self)
    Queues the email to be sent after the commit of the current cursor. Useful to send an email only if a transaction is successful.
  • unlink(self)
  • write(self, vals)

New fields (43)
  • attachment_ids Many2many → ir.attachment
    bypass_search_access=True string='Attachments' args: 'ir.attachment', 'message_attachment_rel', 'message_id', 'attachment_id'
  • author_avatar Binary
    depends=['author_id'] readonly=False related='author_id.avatar_128' args: "Author's avatar"
  • author_guest_id Many2one → mail.guest
    comodel_name='mail.guest' string='Guest'
  • author_id Many2one → res.partner
    help='Author of the message. If not set, email_from may hold an email address that did not match any partner.' index=True ondelete='set null' args: 'res.partner', 'Author'
  • body Html
    default='' sanitize_style=True args: 'Contents'
  • child_ids One2many → mail.message
    args: 'mail.message', 'parent_id', 'Child Messages'
  • date Datetime
    default=fields.Datetime.now args: 'Date'
  • email_add_signature Boolean
    default=True
  • email_from Char
    help='Email address of the sender. This field is set when no matching partner is found and replaces the author_id field in the chatter.' args: 'From'
  • email_layout_xmlid Char
    copy=False args: 'Layout'
  • has_error Boolean
    compute='_compute_has_error' search='_search_has_error' args: 'Has error'
  • incoming_email_cc Char
    args: 'Emails Cc'
  • incoming_email_to Text
    args: 'Emails To'
  • is_current_user_or_guest_author Boolean
    compute='_compute_is_current_user_or_guest_author'
  • is_internal Boolean
    help='Hide to public / portal users, independently from subtype configuration.' args: 'Employee Only'
  • linked_message_ids Many2many → mail.message
    compute='_compute_linked_message_ids' args: 'mail.message'
  • mail_activity_type_id Many2one → mail.activity.type
    index='btree_not_null' ondelete='set null' args: 'mail.activity.type', 'Mail Activity Type'
  • mail_ids One2many → mail.mail
    groups='base.group_system' string='Mails' args: 'mail.mail', 'mail_message_id'
  • mail_server_id Many2one → ir.mail_server
    args: 'ir.mail_server', 'Outgoing mail server'
  • message_id Char
    copy=False help='Message unique identifier' index='btree' readonly=True args: 'Message-Id'
  • message_link_preview_ids One2many → mail.message.link.preview
    groups='base.group_erp_manager' args: 'mail.message.link.preview', 'message_id'
  • message_type Selection
    default='comment' help="Used to categorize message generator\n'email': generated by an incoming email e.g. mailgateway\n'comment': generated by user input e.g. through discuss or composer\n'email_outgoing': generated by a mailing\n'notification': generated by system e.g. tracking messages\n'auto_comment': generated by automated notification mechanism e.g. acknowledgment\n'user_notification': generated for a specific recipient" required=True args: [('email', 'Incoming Email'), ('comment', 'Comment'), ('email_outgoing', 'Outgoing Email'), ('notification', 'System notification'), ('auto_comment', 'Automated Targeted Notification'), ('out_of_office', 'Out-of-office Message'), ('user_notification', 'User Specific Notification')], 'Type'
  • model Char
    args: 'Related Document Model'
  • needaction Boolean
    compute='_compute_needaction' search='_search_needaction' args: 'Need Action'
  • notification_ids One2many → mail.notification
    bypass_search_access=True copy=False depends=['notified_partner_ids'] args: 'mail.notification', 'mail_message_id', 'Notifications'
  • notified_partner_ids Many2many → res.partner
    context={'active_test': False} copy=False depends=['notification_ids'] string='Partners with Need Action' args: 'res.partner', 'mail_notification'
  • outgoing_email_to Char
    args: 'emails To'
  • parent_id Many2one → mail.message
    index='btree_not_null' ondelete='set null' args: 'mail.message', 'Parent Message'
  • partner_ids Many2many → res.partner
    context={'active_test': False} string='Recipients' args: 'res.partner'
  • pinned_at Datetime
    help='Datetime at which the message has been pinned' args: 'Pinned'
  • preview Char
    compute='_compute_preview' help='The text-only beginning of the body used as email preview.' args: 'Preview'
  • reaction_ids One2many → mail.message.reaction
    groups='base.group_system' string='Reactions' args: 'mail.message.reaction', 'message_id'
  • record_alias_domain_id Many2one → mail.alias.domain
    ondelete='set null' args: 'mail.alias.domain', 'Alias Domain'
  • record_company_id Many2one → res.company
    ondelete='set null' args: 'res.company', 'Company'
  • record_name Char
    compute='_compute_record_name' store=False args: 'Message Record Name'
  • reply_to Char
    help='Reply email address. Setting the reply_to bypasses the automatic thread creation.' args: 'Reply-To'
  • reply_to_force_new Boolean
    help='If true, answers do not go in the original document discussion thread. Instead, it will check for the reply_to in tracking message-id and redirected accordingly. This has an impact on the generated message-id.' args: 'No threading for answers'
  • res_id Many2oneReference
    model_field='model' args: 'Related Document ID'
  • starred Boolean
    compute='_compute_starred' compute_sudo=False help='Current user has a starred notification linked to this message' search='_search_starred' args: 'Starred'
  • starred_partner_ids Many2many → res.partner
    string='Favorited By' args: 'res.partner', 'mail_message_res_partner_starred_rel'
  • subject Char
    args: 'Subject'
  • subtype_id Many2one → mail.message.subtype
    index=True ondelete='set null' args: 'mail.message.subtype', 'Subtype'
  • tracking_value_ids One2many → mail.tracking.value
    groups='base.group_system' help='Tracked values are stored in a separate model. This field allow to reconstruct the tracking and to generate statistics on the model.' string='Tracking values' args: 'mail.tracking.value', 'mail_message_id'
Public methods (13)
  • action_open_document(self)
    Opens the related record based on the model and ID
  • copy_data(self, default=None)
    Make is symmetric to read, to avoid spurious issues with recordsets differences.
  • create(self, vals_list)
    @api.model_create_multi
  • default_get(self, fields)
    @api.model
  • export_data(self, fields_to_export)
  • fetch(self, field_names=None)
  • mark_all_as_read(self, domain=None)
    @api.model
  • read(self, fields=None, load='_classic_read')
    Override to explicitely call check_access(), that is not called by the ORM. It instead directly fetches ir.rules and apply them.
  • set_message_done(self)
    Remove the needaction from messages for the current partner.
  • toggle_message_starred(self)
    Toggle messages as (un)starred. Technically, the notifications related to uid are set to (un)starred.
  • unlink(self)
  • unstar_all(self)
    @api.model
    Unstar messages for the current partner.
  • write(self, vals)

New fields (2)
  • call_history_ids One2many → discuss.call.history
    args: 'discuss.call.history', 'start_call_message_id'
  • channel_id Many2one → discuss.channel
    compute='_compute_channel_id' args: 'discuss.channel'
Public methods (0)

No public methods.

New fields (5)
  • author_id Many2one
    related='message_id.author_id'
  • is_hidden Boolean
  • link_preview_id Many2one → mail.link.preview
    index=True ondelete='cascade' required=True args: 'mail.link.preview'
  • message_id Many2one → mail.message
    index=True ondelete='cascade' required=True args: 'mail.message'
  • sequence Integer
    args: 'Sequence'
Public methods (0)

No public methods.

New fields (4)
  • content Char
    readonly=True required=True string='Content'
  • guest_id Many2one → mail.guest
    comodel_name='mail.guest' ondelete='cascade' readonly=True string='Reacting Guest'
  • message_id Many2one → mail.message
    comodel_name='mail.message' index=True ondelete='cascade' readonly=True required=True string='Message'
  • partner_id Many2one → res.partner
    comodel_name='res.partner' ondelete='cascade' readonly=True string='Reacting Partner'
Public methods (0)

No public methods.

New fields (3)
  • mail_message_id Many2one → mail.message
    ondelete='cascade' required=True string='Message' args: 'mail.message'
  • notification_parameters Text
    args: 'Notification Parameter'
  • scheduled_datetime Datetime
    help='Datetime at which notification should be sent.' required=True args: 'Scheduled Send Date'
Public methods (2)
  • create(self, vals_list)
    @api.model_create_multi
  • force_send(self)
    Launch notification process independently from the expected date.

New fields (10)
  • default Boolean
    default=True help='Activated by default when subscribing.' args: 'Default'
  • description Text
    help='Description that will be added in the message posted for this subtype. If void, the name will be added instead.' prefetch=True translate=True args: 'Description'
  • hidden Boolean
    help='Hide the subtype in the follower options' args: 'Hidden'
  • internal Boolean
    help='Messages with internal subtypes will be visible only by employees, aka members of base_user group' args: 'Internal Only'
  • name Char
    help='Message subtype gives a more precise type on the message, especially for system notifications. For example, it can be a notification related to a new record (New), or to a stage change in a process (Stage change). Message subtypes allow to precisely tune the notifications the user want to receive on its wall.' required=True translate=True args: 'Message Type'
  • parent_id Many2one → mail.message.subtype
    help='Parent subtype, used for automatic subscription. This field is not correctly named. For example on a project, the parent_id of project subtypes refers to task-related subtypes.' ondelete='set null' string='Parent' args: 'mail.message.subtype'
  • relation_field Char
    help='Field used to link the related model to the subtype model when using automatic subscription on a related document. The field is used to compute getattr(related_document.relation_field).' args: 'Relation field'
  • res_model Char
    help='Model the subtype applies to. If False, this subtype applies to all models.' args: 'Model'
  • sequence Integer
    default=1 help='Used to order subtypes.' args: 'Sequence'
  • track_recipients Boolean
    help='Whether to display all the recipients or only the important ones.' args: 'Track Recipients'
Public methods (4)
  • create(self, vals_list)
    @api.model_create_multi
  • default_subtypes(self, model_name)
    @api.model
    Retrieve the default subtypes (all, internal, external) for the given model.
  • unlink(self)
  • write(self, vals)

New fields (5)
  • body Html
    help='String received from the translation request.' required=True sanitize_style=True args: 'Translation Body'
  • create_date Datetime
    index=True
  • message_id Many2one → mail.message
    ondelete='cascade' required=True args: 'mail.message', 'Message'
  • source_lang Char
    help='Result of the language detection based on its content.' required=True args: 'Source Language'
  • target_lang Char
    help='Shortened language code used as the target for the translation request.' required=True args: 'Target Language'
Public methods (0)

No public methods.

New fields (11)
  • author_id Many2one → res.partner
    ondelete='set null' args: 'res.partner', 'Author'
  • failure_reason Text
    copy=False args: 'Failure reason'
  • failure_type Selection
    selection=[('unknown', 'Unknown error'), ('mail_bounce', 'Bounce'), ('mail_spam', 'Detected As Spam'), ('mail_email_invalid', 'Invalid email address'), ('mail_email_missing', 'Missing email address'), ('mail_from_invalid', 'Invalid from address'), ('mail_from_missing', 'Missing from address'), ('mail_smtp', 'Connection failed (outgoing mail server problem)'), ('mail_bl', 'Blacklisted Address'), ('mail_optout', 'Opted Out'), ('mail_dup', 'Duplicated Email')] string='Failure type'
  • is_read Boolean
    index=True args: 'Is Read'
  • mail_email_address Char
    help='Recipient email address'
  • mail_mail_id Many2one → mail.mail
    help='Optional mail_mail ID. Used mainly to optimize searches.' index=True args: 'mail.mail', 'Mail'
  • mail_message_id Many2one → mail.message
    index=True ondelete='cascade' required=True args: 'mail.message', 'Message'
  • notification_status Selection
    default='ready' index=True string='Status' args: [('ready', 'Ready to Send'), ('process', 'Processing'), ('pending', 'Sent'), ('sent', 'Delivered'), ('bounce', 'Bounced'), ('exception', 'Exception'), ('canceled', 'Cancelled')]
  • notification_type Selection
    default='inbox' index=True required=True string='Notification Type' args: [('inbox', 'Inbox'), ('email', 'Email')]
  • read_date Datetime
    copy=False args: 'Read Date'
  • res_partner_id Many2one → res.partner
    index=True ondelete='cascade' args: 'res.partner', 'Recipient'
Public methods (3)
  • create(self, vals_list)
    @api.model_create_multi
  • format_failure_reason(self)
  • write(self, vals)

New fields (5)
  • guest_id Many2one → mail.guest
    ondelete='cascade' args: 'mail.guest', 'Guest'
  • last_poll Datetime
    default=<expr> args: 'Last Poll'
  • last_presence Datetime
    default=<expr> args: 'Last Presence'
  • status Selection
    default='offline' args: [('online', 'Online'), ('away', 'Away'), ('offline', 'Offline')], 'IM Status'
  • user_id Many2one → res.users
    ondelete='cascade' args: 'res.users', 'Users'
Public methods (3)
  • create(self, vals_list)
    @api.model_create_multi
  • unlink(self)
  • write(self, vals)

New fields (2)
  • mail_push_device_id Many2one → mail.push.device
    ondelete='cascade' required=True string='devices' args: 'mail.push.device'
  • payload Text
Public methods (0)

No public methods.

New fields (4)
  • endpoint Char
    required=True string='Browser endpoint'
  • expiration_time Datetime
    string='Expiration Token Date'
  • keys Char
    help="It's refer to browser keys used by the notification: \n- p256dh: It's the subscription public key generated by the browser. The browser will \n keep the private key secret and use it for decrypting the payload\n- auth: The auth value should be treated as a secret and not shared outside of Odoo" required=True string='Browser keys'
  • partner_id Many2one → res.partner
    default=<expr> index=True required=True string='Partner' args: 'res.partner'
Public methods (3)
  • get_web_push_vapid_public_key(self)
    @api.model
  • register_devices(self, **kw)
    @api.model
  • unregister_devices(self, **kw)
    @api.model

New fields (2)
  • lang Char
    help="Optional translation language (ISO code) to select when sending out an email. If not set, the main partner's language will be used. This should usually be a placeholder expression that provides the appropriate language, e.g. {{ object.partner_id.lang }}." args: 'Language'
  • render_model Char
    compute='_compute_render_model' store=False args: 'Rendering Model'
Public methods (2)
  • create(self, vals_list)
    @api.model_create_multi
  • write(self, vals)

New fields (12)
  • attachment_ids Many2many → ir.attachment
    bypass_search_access=True string='Attachments' args: 'ir.attachment', 'scheduled_message_attachment_rel', 'scheduled_message_id', 'attachment_id'
  • author_id Many2one → res.partner
    required=True args: 'res.partner', 'Author'
  • body Html
    sanitize_style=True args: 'Contents'
  • composition_comment_option Selection
    string='Comment Options' args: [('reply_all', 'Reply-All'), ('forward', 'Forward')]
  • is_note Boolean
    default=False help='If the message will be posted as a Note.' args: 'Is a note'
  • model Char
    required=True args: 'Related Document Model'
  • notification_parameters Text
    args: 'Notification parameters'
  • partner_ids Many2many → res.partner
    string='Recipients' args: 'res.partner'
  • res_id Many2oneReference
    model_field='model' required=True args: 'Related Document Id'
  • scheduled_date Datetime
    required=True args: 'Scheduled Date'
  • send_context Json
    args: 'Sending Context'
  • subject Char
    args: 'Subject'
Public methods (5)
  • create(self, vals_list)
    @api.model_create_multi
  • open_edit_form(self)
  • post_message(self)
  • unlink(self)
  • write(self, vals)

New fields (26)
  • active Boolean
    default=True
  • attachment_ids Many2many → ir.attachment
    bypass_search_access=True string='Attachments' args: 'ir.attachment', 'email_template_attachment_rel', 'email_template_id', 'attachment_id'
  • auto_delete Boolean
    default=True help="This option permanently removes any track of email after it's been sent, including from the Technical menu in the Settings, in order to preserve storage space of your Odoo database." args: 'Auto Delete'
  • body_html Html
    prefetch=True render_engine='qweb' render_options={'post_process': True} sanitize='email_outgoing' translate=True args: 'Body'
  • can_write Boolean
    compute='_compute_can_write' help='The current user can edit the template.'
  • description Text
    help="This field is used for internal description of the template's usage." translate=True args: 'Template Description'
  • email_cc Char
    help='Carbon copy recipients (placeholders may be used here)' args: 'Cc'
  • email_from Char
    help="Sender address (placeholders may be used here). If not set, the default value will be the author's email alias if configured, or email address." args: 'Send From'
  • email_layout_xmlid Char
    copy=False args: 'Email Notification Layout'
  • email_to Char
    help='Comma-separated recipient addresses (placeholders may be used here)' args: 'To (Emails)'
  • has_dynamic_reports Boolean
    compute='_compute_has_dynamic_reports'
  • has_mail_server Boolean
    compute='_compute_has_mail_server'
  • is_template_editor Boolean
    compute='_compute_is_template_editor'
  • mail_server_id Many2one → ir.mail_server
    help='Optional preferred server for outgoing mails. If not set, the highest priority one will be used.' index='btree_not_null' readonly=False args: 'ir.mail_server', 'Outgoing Mail Server'
  • model Char
    index=True readonly=True related='model_id.model' store=True args: 'Related Document Model'
  • model_id Many2one → ir.model
    domain=_get_non_abstract_models_domain ondelete='cascade' args: 'ir.model', 'Applies to'
  • name Char
    translate=True args: 'Name'
  • partner_to Char
    help='Comma-separated ids of recipient partners (placeholders may be used here)' args: 'To (Partners)'
  • ref_ir_act_window Many2one → ir.actions.act_window
    copy=False help='Sidebar action to make this template available on records of the related document model' readonly=True args: 'ir.actions.act_window', 'Sidebar action'
  • reply_to Char
    help='Email address to which replies will be redirected when sending emails in mass; only used when the reply is not logged in the original discussion thread.' args: 'Reply To'
  • report_template_ids Many2many → ir.actions.report
    column1='mail_template_id' column2='ir_actions_report_id' domain="[('model', '=', model)]" relation='mail_template_ir_actions_report_rel' string='Dynamic Reports' args: 'ir.actions.report'
  • scheduled_date Char
    help='If set, the queue manager will send the email after the date. If not set, the email will be send as soon as possible. You can use dynamic expression.' args: 'Scheduled Date'
  • subject Char
    help='Subject (placeholders may be used here)' prefetch=True translate=True args: 'Subject'
  • template_category Selection
    compute='_compute_template_category' search='_search_template_category' args: [('base_template', 'Base Template'), ('hidden_template', 'Hidden Template'), ('custom_template', 'Custom Template')]
  • use_default_to Boolean
    default=True help='Default recipients of the record:\n- partner (using id on a partner or the partner_id field) OR\n- email (using email_from or email field)' args: 'Default Recipients'
  • user_id Many2one → res.users
    domain="[('share', '=', False)]" string='Owner' args: 'res.users'
Public methods (11)
  • action_open_mail_preview(self)
  • copy(self, default=None)
  • copy_data(self, default=None)
  • create(self, vals_list)
    @api.model_create_multi
  • create_action(self)
  • default_get(self, fields)
    @api.model
  • send_mail(self, res_id, force_send=False, raise_exception=False, email_values=None, email_layout_xmlid=False)
    Generates a new mail.mail. Template is rendered on record given by res_id and model coming from template. :param int res_id: id of the record to render the template :param bool force_send: send email immediately; otherwise use the mail queue (recommended); :param dict email_values: update generated mail with those values to further customize the mail; :param str email_layout_xmlid: optional notification layout to encapsulate the generated email; :returns: id of the mail.mail that was created
  • send_mail_batch(self, res_ids, force_send=False, raise_exception=False, email_values=None, email_layout_xmlid=False)
    Generates new mail.mails. Batch version of 'send_mail'.' :param list res_ids: IDs of modelrecords on which template will be rendered :returns: newly created mail.mail
  • unlink(self)
  • unlink_action(self)
  • write(self, vals)

New fields (17)
  • attachment_ids Many2many → ir.attachment
    compute='_compute_mail_template_fields' string='Attachments' args: 'ir.attachment'
  • body_html Html
    compute='_compute_mail_template_fields' sanitize=False args: 'Body'
  • email_cc Char
    compute='_compute_mail_template_fields' help='Carbon copy recipients' args: 'Cc'
  • email_from Char
    compute='_compute_mail_template_fields' help='Sender address' args: 'From'
  • email_to Char
    compute='_compute_mail_template_fields' help='Comma-separated recipient addresses' args: 'To'
  • error_msg Char
    compute='_compute_mail_template_fields' args: 'Error Message'
  • has_attachments Boolean
    compute='_compute_has_attachments'
  • has_several_languages_installed Boolean
    compute='_compute_has_several_languages_installed'
  • lang Selection
    string='Template Preview Language' args: _selection_languages
  • mail_template_id Many2one → mail.template
    required=True string='Related Mail Template' args: 'mail.template'
  • model_id Many2one → ir.model
    related='mail_template_id.model_id' string='Targeted model' args: 'ir.model'
  • no_record Boolean
    compute='_compute_no_record' args: 'No Record'
  • partner_ids Many2many → res.partner
    compute='_compute_mail_template_fields' string='Recipients' args: 'res.partner'
  • reply_to Char
    compute='_compute_mail_template_fields' help='Preferred response address' args: 'Reply-To'
  • resource_ref Reference
    compute='_compute_resource_ref' compute_sudo=False readonly=False selection='_selection_target_model' store=True string='Record'
  • scheduled_date Char
    compute='_compute_mail_template_fields' help='The queue manager will send the email after the date' args: 'Scheduled Date'
  • subject Char
    compute='_compute_mail_template_fields' args: 'Subject'
Public methods (0)

No public methods.

New fields (1)
  • template_ids Many2many → mail.template
    args: 'mail.template'
Public methods (1)
  • reset_template(self)

New fields (10)
  • has_message Boolean
    compute='_compute_has_message' search='_search_has_message' store=False
  • message_attachment_count Integer
    compute='_compute_message_attachment_count' groups='base.group_user' args: 'Attachment Count'
  • message_follower_ids One2many → mail.followers
    groups='base.group_user' string='Followers' args: 'mail.followers', 'res_id'
  • message_has_error Boolean
    compute='_compute_message_has_error' help='If checked, some messages have a delivery error.' search='_search_message_has_error' args: 'Message Delivery error'
  • message_has_error_counter Integer
    compute='_compute_message_has_error' help='Number of messages with delivery error' args: 'Number of errors'
  • message_ids One2many → mail.message
    bypass_search_access=True domain=<expr> string='Messages' args: 'mail.message', 'res_id'
  • message_is_follower Boolean
    compute='_compute_message_is_follower' search='_search_message_is_follower' args: 'Is Follower'
  • message_needaction Boolean
    compute='_compute_message_needaction' help='If checked, new messages require your attention.' search='_search_message_needaction' args: 'Action Needed'
  • message_needaction_counter Integer
    compute='_compute_message_needaction' help='Number of messages requiring action' args: 'Number of Actions'
  • message_partner_ids Many2many → res.partner
    comodel_name='res.partner' compute='_compute_message_partner_ids' groups='base.group_user' inverse='_inverse_message_partner_ids' search='_search_message_partner_ids' string='Followers (Partners)'
Public methods (20)
  • copy_data(self, default=None)
  • create(self, vals_list)
    @api.model_create_multi
    Chatter override : - subscribe uid - subscribe followers of parent - log a creation message
  • get_empty_list_help(self, help_message)
    @api.model
    Override of BaseModel.get_empty_list_help() to generate an help message that adds alias information.
  • get_views(self, views, options=None)
    @api.model
  • message_change_thread(self, new_thread, new_parent_message=False)
    Transfer the list of the mail thread messages from an model to another :param id : the old res_id of the mail.message :param new_res_id : the new res_id of the mail.message :param new_model : the name of the new model of the mail.message Example : my_lead.message_change_thread(my_project_task) will transfer the context of the thread of my_lead to my_project_task
  • message_get_followers(self, after=None, limit=100, filter_recipients=False)
    @api.readonly
  • message_mail_with_source(self, source_ref, *, render_values=None, message_type='notification', auto_commit=False, **kwargs)
    Send a mass mail on self, using an external source to render part of the content. It can be either a 'mail.template', either a view used to render the body using QWeb. SPOILER: this method currently calls a composer in a loop when using a view even if it is suboptimal. This is due to current composer implementation.. This will be cleaned soon to optimize mass mailing through mail.thread and lessen usage of composer itself. Default values * subtype_id: will be False, forced by composer in mass mode; :param record/str source_ref: reference to a source for rendering. It can be one of * a MailTemplate record. It will be used to render the various message values (body, subject, recipients, ...). It should behave like using the mail composer with a template; * an IrUIView record. It will be used to render the content (body). Other fields are left to the caller and/or default values computation; * an XmlID of a MailTemplate or of an IrUiView: see above; :param dict render_values: additional rendering values for qweb context; :param str message_type: one of 'notification' or 'comment'; :param bool auto_commit: auto commit after each batch of emails sent (see ``MailComposer._action_send_mail()``); :param dict kwargs: additional values given to the 'mail.compose.message' creation; :return: created mail.mail records, as sudo
  • message_new(self, msg_dict, custom_values=None)
    @api.model
    Called by ``message_process`` when a new message is received for a given thread model, if the message did not belong to an existing thread. The default behavior is to create a new record of the corresponding model (based on some very basic info extracted from the message). Additional behavior may be implemented by overriding this method. :param dict msg_dict: a map containing the email details and attachments. See ``message_process`` and ``mail.message.parse`` for details. :param dict custom_values: optional dictionary of additional field values to pass to create() when creating the new thread record. Be careful, these values may override any other values coming from the message. :rtype: int :return: the id of the newly created thread object
  • message_notify(self, *, body='', subject=False, author_id=None, email_from=None, model=False, res_id=False, subtype_xmlid=None, subtype_id=False, partner_ids=False, attachments=None, attachment_ids=None, **kwargs)
    Shortcut allowing to notify partners of messages that should not be displayed on a document. It pushes notifications on inbox or by email depending on the user configuration, like other notifications. Default values * subtype_id: if not given, fallback on ``note`` to be consistent with what message_post does; :param str body: body of the message, usually raw HTML that will be sanitized :param str subject: subject of the message :param int author_id: optional ID of partner record being the author. See ``_message_compute_author`` that uses it to make email_from / author_id coherent; :param str email_from: from address of the author. See ``_message_compute_author`` that uses it to make email_from / author_id coherent; :param str model: when invoked on MailThread directly, this method allows to push a notification on a given record (allows to notify on not thread-enabled records); :param int res_id: defines the record in combination with model; :param str subtype_xmlid: optional xml id of a mail.message.subtype to fetch, will force value of subtype_id; :param int subtype_id: subtype_id of the message, used mainly for followers notification mechanism; :param list(int) partner_ids: partner_ids to notify in addition to partners computed based on subtype / followers matching; :param list(tuple(str,str), tuple(str,str, dict)) attachments : list of attachment tuples in the form ``(name,content)`` or ``(name,content, info)`` where content is NOT base64 encoded; :param list attachment_ids: list of existing attachments to link to this message Should not be a list of commands. Attachment records attached to mail composer will be attached to the related document. Extra keyword arguments will be used either * as default column values for the new mail.message record if they match mail.message fields; * propagated to notification methods if not; :return: posted mail.message records
  • message_parse(self, message, save_original=False)
    @api.model
    Parses an email.message.Message representing an RFC-2822 email and returns a generic dict holding the message details. Note that partner finding is delegated to a post processing as it is better done using gateway record as context e.g. to check for followers, ... see '_message_parse_post_process'. :param message: email to parse :type message: email.message.Message :param bool save_original: whether the returned dict should include an ``original`` attachment containing the source of the message :rtype: dict :return: A dict with the following structure, where each field may not be present if missing in original message:: { 'message_id': msg_id, 'subject': subject, 'email_from': from, 'to': to + delivered-to, 'cc': cc, 'recipients': delivered-to + to + cc + resent-to + resent-cc, 'body': unified_body, 'references': references, 'in_reply_to': in-reply-to, 'is_bounce': True if it has been detected as a bounce email 'parent_id': parent mail.message based on in_reply_to or references, 'is_internal': answer to an internal message (note), 'date': date, 'attachments': [('file1', 'bytes'), ('file2', 'bytes')} }
  • message_post(self, *, body='', subject=None, message_type='notification', email_from=None, author_id=None, parent_id=False, subtype_xmlid=None, subtype_id=False, partner_ids=None, outgoing_email_to=False, incoming_email_to=False, incoming_email_cc=False, attachments=None, attachment_ids=None, body_is_html=False, **kwargs)
    Post a new message in an existing thread, returning the new mail.message. :param str|Markup body: body of the message, str content will be escaped, Markup for html body :param str subject: subject of the message :param str message_type: see mail_message.message_type field. Can be anything but user_notification, reserved for message_notify :param str email_from: from address of the author. See ``_message_compute_author`` that uses it to make email_from / author_id coherent; :param int author_id: optional ID of partner record being the author. See ``_message_compute_author`` that uses it to make email_from / author_id coherent; :param int parent_id: handle thread formation :param str subtype_xmlid: optional xml id of a mail.message.subtype to fetch, will force value of subtype_id; :param int subtype_id: subtype_id of the message, used mainly for followers notification mechanism; :param list(int) partner_ids: partner_ids to notify in addition to partners computed based on subtype / followers matching; :param str outgoing_email_to: comma-separated list of emails to notify in addition to partner_ids. Experimental support as of Odoo v19; :param str incoming_email_to: comma-separated list of emails, already notified by incoming email; :param str incoming_email_cc: comma-separated list of emails, already notified by incoming email; :param list(tuple(str,str), tuple(str,str, dict)) attachments : list of attachment tuples in the form ``(name,content)`` or ``(name,content, info)`` where content is NOT base64 encoded; :param list attachment_ids: list of existing attachments to link to this message Should not be a list of commands. Attachment records attached to mail composer will be attached to the related document. :param bool body_is_html: indicates body should be threated as HTML even if str to be used only for RPC calls Extra keyword arguments will be used either * as default column values for the new mail.message record if they match mail.message fields; * propagated to notification methods if not; :return: newly create mail.message record
  • message_post_with_source(self, source_ref, *, render_values=None, message_type='notification', subtype_xmlid=False, subtype_id=False, **kwargs)
    Post a message on each record of self, using a view to render the body using QWeb. Default values * subtype_id: if not given, fallback on ``note`` to be consistent with what message_post does; :param record/str source_ref: reference to a source for rendering. It can be one of * a MailTemplate record. It will be used to render the various message values (body, subject, recipients, ...). It should behave like using the mail composer with a template; * an IrUIView record. It will be used to render the content (body). Other fields are left to the caller and/or default values computation; * an XmlID of a MailTemplate or of an IrUiView: see above :param dict render_values: additional rendering values for qweb context; :param str message_type: one of 'notification' or 'comment'; :param str subtype_xmlid: optional xml id of a mail.message.subtype to fetch, will force value of subtype_id; :param int subtype_id: subtype_id of the message, used mainly for followers notification mechanism; :param dict kwargs: additional values given to the 'mail.compose.message' creation; :return: posted mail.message records
  • message_process(self, model, message, custom_values=None, save_original=False, strip_attachments=False, thread_id=None)
    @api.model
    Process an incoming RFC2822 email message, relying on ``mail.message.parse()`` for the parsing operation, and ``message_route()`` to figure out the target model. Once the target model is known, its ``message_new`` method is called with the new message (if the thread record did not exist) or its ``message_update`` method (if it did). :param str model: the fallback model to use if the message does not match any of the currently configured mail aliases (may be None if a matching alias is supposed to be present) :param message: source of the RFC2822 message :type message: str | xmlrpclib.Binary :param custom_values: optional dictionary of field values to pass to ``message_new`` if a new record needs to be created. Ignored if the thread record already exists, and also if a matching mail.alias was found (aliases define their own defaults) :type custom_values: dict | None :param bool save_original: whether to keep a copy of the original email source attached to the message after it is imported. :param bool strip_attachments: whether to strip all attachments before processing the message, in order to save some space. :param int thread_id: optional ID of the record/thread from ``model`` to which this mail should be attached. When provided, this overrides the automatic detection based on the message headers.
  • message_route(self, message, message_dict, model=None, thread_id=None, custom_values=None)
    @api.model
    Attempt to figure out the correct target model, thread_id, custom_values and user_id to use for an incoming message. Multiple values may be returned, if a message had multiple recipients matching existing mail.aliases, for example. The following heuristics are used, in this order: * if the message replies to an existing thread by having a Message-Id that matches an existing mail_message.message_id, we take the original message model/thread_id pair and ignore custom_value as no creation will take place; * look for a mail.alias entry matching the message recipients and use the corresponding model, thread_id, custom_values and user_id. This could lead to a thread update or creation depending on the alias; * fallback on provided ``model``, ``thread_id`` and ``custom_values``; * raise an exception as no route has been found :param str message: an email.message instance :param dict message_dict: dictionary holding parsed message variables :param str model: the fallback model to use if the message does not match any of the currently configured mail aliases (may be None if a matching alias is supposed to be present) :param custom_values: dictionary mapping field names to default values to be passed to ``message_new`` if a new record needs to be created. Ignored if the thread record already exists, and also if a matching mail.alias was found (aliases define their own defaults) :type custom_values: dict[str, Any] | None :param int thread_id: optional ID of the record/thread from ``model`` to which this mail should be attached. Only used if the message does not reply to an existing thread and does not match any mail alias. :return: list of routes [(model, thread_id, custom_values, user_id, alias)] :raises: ValueError, TypeError
  • message_subscribe(self, partner_ids=None, subtype_ids=None)
    Main public API to add followers to a record set. Its main purpose is to perform access rights checks before calling ``_message_subscribe``.
  • message_unsubscribe(self, partner_ids=None)
    Remove partners from the records followers.
  • message_update(self, msg_dict, update_vals=None)
    Called by ``message_process`` when a new message is received for an existing thread. The default behavior is to update the record with update_vals taken from the incoming email. Additional behavior may be implemented by overriding this method. :param dict msg_dict: a map containing the email details and attachments. See ``message_process`` and ``mail.message.parse()`` for details. :param dict update_vals: a dict containing values to update records given their ids; if the dict is None or is void, no write operation is performed.
  • notify_cancel_by_type(self, notification_type)
    @api.model
    Subclasses must call this method and then * either call the standard implementation _notify_cancel_by_type_generic * or implements their own logic
  • unlink(self)
    Override unlink to delete (scheduled) messages and followers. This cannot be cascaded, because link is done through (res_model, res_id).
  • write(self, vals)

New fields (3)
  • email_normalized Char
    compute='_compute_email_normalized' compute_sudo=True help='This field is used to search on email address as the primary email field can contain more than strictly an email address.' store=True string='Normalized Email'
  • is_blacklisted Boolean
    compute='_compute_is_blacklisted' compute_sudo=True groups='base.group_user' help="If the email address is on the blacklist, the contact won't receive mass mailing anymore, from any list" search='_search_is_blacklisted' store=False string='Blacklist'
  • message_bounce Integer
    default=0 help='Counter of the number of bounced emails for this contact' args: 'Bounce'
Public methods (1)
  • mail_action_blacklist_remove(self)

New fields (1)
  • email_cc Char
    args: 'Email cc'
Public methods (2)
  • message_new(self, msg_dict, custom_values=None)
    @api.model
  • message_update(self, msg_dict, update_vals=None)

New fields (1)
  • message_main_attachment_id Many2one → ir.attachment
    comodel_name='ir.attachment' copy=False index='btree_not_null' string='Main Attachment'
Public methods (0)

No public methods.

New fields (3)
  • duration_tracking Json
    compute='_compute_duration_tracking' help='JSON that maps ids from a many2one field to seconds spent' string='Status time'
  • is_rotting Boolean
    compute='_compute_rotting' search='_search_is_rotting' args: 'Rotting'
  • rotting_days Integer
    compute='_compute_rotting' help='Day count since this resource was last updated' args: 'Days Rotting'
Public methods (0)

No public methods.

New fields (14)
  • currency_id Many2one → res.currency
    help='Used to display the currency when tracking monetary values' ondelete='set null' readonly=True args: 'res.currency', 'Currency'
  • field_id Many2one → ir.model.fields
    index=True ondelete='set null' readonly=True required=False args: 'ir.model.fields'
  • field_info Json
    args: 'Removed field information'
  • mail_message_id Many2one → mail.message
    index=True ondelete='cascade' required=True args: 'mail.message', 'Message ID'
  • new_value_char Char
    readonly=True args: 'New Value Char'
  • new_value_datetime Datetime
    readonly=True args: 'New Value Datetime'
  • new_value_float Float
    readonly=True args: 'New Value Float'
  • new_value_integer Integer
    readonly=True args: 'New Value Integer'
  • new_value_text Text
    readonly=True args: 'New Value Text'
  • old_value_char Char
    readonly=True args: 'Old Value Char'
  • old_value_datetime Datetime
    readonly=True args: 'Old Value DateTime'
  • old_value_float Float
    readonly=True args: 'Old Value Float'
  • old_value_integer Integer
    readonly=True args: 'Old Value Integer'
  • old_value_text Text
    readonly=True args: 'Old Value Text'
Public methods (0)

No public methods.

New fields (0)

No new fields.

Public methods (1)
  • update_notification(self, cron_mode=True)
    Send a message to Odoo's publisher warranty server to check the validity of the contracts, get notifications, etc... @param cron_mode: If true, catch all exceptions (appropriate for usage in a cron). @type cron_mode: boolean

New fields (9)
  • alias_domain_id Many2one → mail.alias.domain
    default=<expr> index='btree_not_null' string='Email Domain' args: 'mail.alias.domain'
  • bounce_email Char
    compute='_compute_bounce' string='Bounce Email'
  • bounce_formatted Char
    compute='_compute_bounce' string='Bounce'
  • catchall_email Char
    compute='_compute_catchall' string='Catchall Email'
  • catchall_formatted Char
    compute='_compute_catchall' string='Catchall'
  • default_from_email Char
    readonly=True related='alias_domain_id.default_from_email' string='Default From'
  • email_formatted Char
    compute='_compute_email_formatted' compute_sudo=True string='Formatted Email'
  • email_primary_color Char
    default='#FFFFFF' readonly=False args: 'Email Button Text'
  • email_secondary_color Char
    default='#875A7B' readonly=False args: 'Email Button Color'
Public methods (0)

No public methods.

New fields (16)
  • alias_domain_id Many2one → mail.alias.domain
    help='If you have setup a catch-all email domain redirected to the Odoo server, enter the domain name here.' readonly=False related='company_id.alias_domain_id' args: 'mail.alias.domain', 'Alias Domain'
  • email_primary_color Char
    readonly=False related='company_id.email_primary_color'
  • email_secondary_color Char
    readonly=False related='company_id.email_secondary_color'
  • external_email_server_default Boolean
    config_parameter='base_setup.default_external_email_server' args: 'Use Custom Email Servers'
  • fail_counter Integer
    compute='_compute_fail_counter' args: 'Fail Mail'
  • google_translate_api_key Char
    config_parameter='mail.google_translate_api_key' help='A valid Google API key is required to enable message translation. https://cloud.google.com/translate/docs/setup' args: 'Message Translation API Key'
  • module_google_gmail Boolean
    args: 'Support Gmail Authentication'
  • module_microsoft_outlook Boolean
    args: 'Support Outlook Authentication'
  • restrict_template_rendering Boolean
    config_parameter='mail.restrict.template.rendering' help='Users will still be able to render templates.\nHowever only Mail Template Editors will be able to create new dynamic templates or modify existing ones.' args: 'Restrict Template Rendering'
  • sfu_server_key Char
    config_parameter='mail.sfu_server_key' help='Base64 encoded key' args: 'SFU Server key'
  • sfu_server_url Char
    config_parameter='mail.sfu_server_url' args: 'SFU Server URL'
  • tenor_api_key Char
    config_parameter='discuss.klipy_api_key' help='Add a Klipy GIF API key to enable GIFs support. https://docs.klipy.com/getting-started\nIf you were using a Tenor GIF API key (service shutdown on June 30, 2026), please replace it here with a Klipy GIF API key' args: 'Klipy API key'
  • twilio_account_sid Char
    config_parameter='mail.twilio_account_sid' args: 'Account SID'
  • twilio_account_token Char
    config_parameter='mail.twilio_account_token' args: 'Account Auth Token'
  • use_sfu_server Boolean
    config_parameter='mail.use_sfu_server' help='If you want to setup SFU server for large group calls.' args: 'Use SFU server'
  • use_twilio_rtc_servers Boolean
    config_parameter='mail.use_twilio_rtc_servers' help='If you want to use twilio as TURN/STUN server provider' args: 'Use Twilio ICE servers'
Public methods (2)
  • open_email_layout(self)
  • open_mail_templates(self)

New fields (0)

No new fields.

Public methods (1)
  • write(self, vals)

New fields (9)
  • contact_address_inline Char
    compute='_compute_contact_address_inline' string='Inlined Complete Address' tracking=True
  • email Char
    tracking=1
  • im_status Char
    compute='_compute_im_status' compute_sudo=True args: 'IM Status'
  • name Char
    tracking=1
  • offline_since Datetime
    compute='_compute_im_status' compute_sudo=True args: 'Offline since'
  • parent_id Many2one
    tracking=3
  • phone Char
    tracking=2
  • user_id Many2one
    tracking=4
  • vat Char
    tracking=5
Public methods (2)
  • find_or_create(self, email, assert_valid_email=False)
    @api.model
    Override to use the email_normalized field.
  • get_mention_suggestions(self, search, limit=8)
    @api.readonly@api.model
    Return 'limit'-first partners' such that the name or email matches a 'search' string. Prioritize partners that are also (internal) users, and then extend the research to all partners. The return format is a list of partner data (as per returned by `_to_store()`).

New fields (4)
  • channel_ids Many2many → discuss.channel
    copy=False string='Channels' args: 'discuss.channel', 'discuss_channel_member', 'partner_id', 'channel_id'
  • channel_member_ids One2many → discuss.channel.member
    args: 'discuss.channel.member', 'partner_id'
  • is_in_call Boolean
    compute='_compute_is_in_call' groups='base.group_system'
  • rtc_session_ids One2many → discuss.channel.rtc.session
    args: 'discuss.channel.rtc.session', 'partner_id'
Public methods (2)
  • get_mention_suggestions_from_channel(self, channel_id, search, limit=8)
    @api.readonly@api.model
    Return 'limit'-first partners' such that the name or email matches a 'search' string. Prioritize partners that are also (internal) users, and then extend the research to all partners. Only members of the given channel are returned. The return format is a list of partner data (as per returned by `_to_store()`).
  • search_for_channel_invite(self, search_term, channel_id=None, limit=30)
    @api.readonly@api.model
    Returns partners matching search_term that can be invited to a channel. - If `channel_id` is specified, only partners that can actually be invited to the channel are returned (not already members, and in accordance to the channel configuration). - If no matching partners are found and the search term is a valid email address, then the method may return `selectable_email` as a fallback direct email invite, provided that the channel allows invites by email.

New fields (2)
  • name Char
    required=True
  • user_ids Many2many → res.users
    relation='res_role_res_users_rel' string='Users' args: 'res.users'
Public methods (0)

No public methods.

New fields (13)
  • can_edit_role Boolean
    compute='_compute_can_edit_role'
  • has_external_mail_server Boolean
    compute='_compute_has_external_mail_server'
  • im_status Char
    compute='_compute_im_status' compute_sudo=True args: 'IM Status'
  • is_out_of_office Boolean
    compute='_compute_is_out_of_office' args: 'Out of Office'
  • manual_im_status Selection
    string='IM status manually set by the user' args: [('away', 'Away'), ('busy', 'Do Not Disturb'), ('offline', 'Offline')]
  • notification_type Selection
    compute='_compute_notification_type' default='email' help='Policy on how to handle Chatter notifications:\n- By Emails: notifications are sent to your email address\n- In Odoo: notifications appear in your Odoo Inbox' inverse='_inverse_notification_type' required=True store=True args: [('email', 'By Emails'), ('inbox', 'In Odoo')], 'Notification'
  • out_of_office_from Datetime
  • out_of_office_message Html
    args: 'Vacation Responder'
  • out_of_office_to Datetime
  • outgoing_mail_server_id Many2one → ir.mail_server
    compute='_compute_outgoing_mail_server_id' groups='base.group_user' args: 'ir.mail_server', 'Outgoing Mail Server'
  • outgoing_mail_server_type Selection
    compute='_compute_outgoing_mail_server_id' default='default' groups='base.group_user' required=True args: [('default', 'Default')], 'Outgoing Mail Server Type'
  • presence_ids One2many → mail.presence
    groups='base.group_system' args: 'mail.presence', 'user_id'
  • role_ids Many2many → res.role
    help='Users are notified whenever one of their roles is @-mentioned in a conversation.' relation='res_role_res_users_rel' string='User Roles' args: 'res.role'
Public methods (7)
  • SELF_READABLE_FIELDS(self)
    @property
  • SELF_WRITEABLE_FIELDS(self)
    @property
  • action_archive(self)
  • action_setup_outgoing_mail_server(self, server_type)
    @api.model
    Configure the outgoing mail servers.
  • action_test_outgoing_mail_server(self)
    @api.model
  • create(self, vals_list)
    @api.model_create_multi
  • write(self, vals)

New fields (1)
  • is_in_call Boolean
    related='partner_id.is_in_call' args: 'Is in call'
Public methods (3)
  • create(self, vals_list)
    @api.model_create_multi
  • unlink(self)
  • write(self, vals)

New fields (7)
  • channel_notifications Selection
    help='This setting will only be applied to channels. Mentions only if not specified.' args: [('all', 'All Messages'), ('no_notif', 'Nothing')], 'Channel Notifications'
  • is_discuss_sidebar_category_channel_open Boolean
    default=True string='Is discuss sidebar category channel open?'
  • is_discuss_sidebar_category_chat_open Boolean
    default=True string='Is discuss sidebar category chat open?'
  • push_to_talk_key Char
    help='String formatted to represent a key with modifiers following this pattern: shift.ctrl.alt.key, e.g: truthy.1.true.b' string='Push-To-Talk shortcut'
  • use_push_to_talk Boolean
    default=False string='Use the push to talk feature'
  • voice_active_duration Integer
    default=200 help='How long the audio broadcast will remain active after passing the volume threshold' string='Duration of voice activity in ms'
  • volume_settings_ids One2many → res.users.settings.volumes
    string='Volumes of other partners' args: 'res.users.settings.volumes', 'user_setting_id'
Public methods (2)
  • set_res_users_settings(self, new_settings)
  • set_volume_setting(self, partner_id, volume, guest_id=None)
    Saves the volume of a guest or a partner. Either partner_id or guest_id must be specified. :param float volume: the selected volume between 0 and 1 :param int partner_id: :param int guest_id:

New fields (4)
  • guest_id Many2one → res.partner
    index=True ondelete='cascade' args: 'res.partner'
  • partner_id Many2one → res.partner
    index=True ondelete='cascade' args: 'res.partner'
  • user_setting_id Many2one → res.users.settings
    index=True ondelete='cascade' required=True args: 'res.users.settings'
  • volume Float
    default=0.5 help='Ranges between 0.0 and 1.0, scale depends on the browser implementation'
Public methods (0)

No public methods.

New fields (1)
  • template_fs Char
    copy=False help='File from where the template originates. Used to reset broken template.' string='Template Filename'
Public methods (2)
  • create(self, vals_list)
    @api.model_create_multi
  • reset_template(self)
    Resets the Template with values given in source file. We ignore the case of template being overridden in another modules because it is extremely less likely to happen. This method also tries to reset the translation terms for the current user lang (all langs are not supported due to costly file operation).

Loading…

Loading…

Loading…

Loading…

Loading…

Loading…

Loading…

Loading…

Loading…

Loading…

Loading…

Loading…

Loading…