Discuss
mail · odoo/odoo
Security findings
Migration considerations
- Raw `cr.execute()` INSERT/UPDATE/DELETE bypasses the ORM (no compute/constrains/tracking/mail): `UPDATE mail_canned_response SET last_used=%(last_used)s WHERE id IN ( SELECT id from mail_canned_response WHERE id IN %(ids)s FOR NO KEY UPDATE SKIP LOCKED )` - re-check the table/column names still match after upgrading. migration-raw-sql-write · source
- Raw `cr.execute()` INSERT/UPDATE/DELETE bypasses the ORM (no compute/constrains/tracking/mail): `UPDATE mail_message SET pinned_at=%(pinned_at)s WHERE id=%(id)s` - re-check the table/column names still match after upgrading. migration-raw-sql-write · source
Migration review checklist, not a compatibility verdict. No target version is selected: apply version-specific advice only when migrating to that version or later.
- Repository
- odoo/odoo · module folder
- Module version
- 1.19
- Category
- Productivity/Discuss
- Folder size
- 41.89 MB
- License
- LGPL-3
- Application
- Yes
- Auto-installable
- No
- Website
- https://www.odoo.com/app/discuss
- Last tracking update
- 2026-10-05 12:14:54
- Authors
- Odoo S.A.
- Maintainers
- Odoo S.A.
- Committers
- Xavier Morel, Xavier ALT, Raphael Collet, Thibault Delavallée, odoo, Odoo Translation Bot, Christophe Matthieu, Aaron Bohy, Géry Debongnie, Jeremy Kersten, Lucas Perais (lpe), Yannick Tivisse, qsm-odoo, Odoo Online, Pierre Masereel, Jorge Pinna Puissant, Julien Castiaux, Xavier-Do, Romeo Fragomeli, Victor Feyens, Andrea Grazioso (agr-odoo), Adrien Dieudonné, Paul Morelle, Sébastien Theys, Julien Mougenot, Anh Thao Pham (pta), std-odoo, Achraf (abz), David Beguin, Brice bib Bartoletti, Prakash Prajapati, Rémy Voet (ryv), Tiffany Chang (tic), ThanhDodeurOdoo, Gorash, Mathieu Duckerts-Antoine, Pierre Paridans, abd-msyukyu-odoo, Romain Estievenart, Miquel Raïch, Stanislas Sobieski, william-andre, Didier (did), Antoine Guenet, Florian Charlier, Nicolas Bayet, Jinjiu Liu, luvi, Renaud Thiry, Julien Banken, bve-odoo, David Monnom (moda), tsm-odoo, Louis Wicket (wil), Gaetan Vanden Bergh (gavb), Yash Vaishnav, Victor Piryns (pivi), Thomas Becquevort (thbe), Mahamadasif Ansari, amdi-odoo, Pierre-Yves Dufays, Levi Siuzdak (sile), Dylan Kiss (dyki), Mayurrajsinh Rathod, Rahul Prajapati, Chong Wang (cwg), Adrien Schoffeniels, bram1000, Xavier Bol (xbo), Brieuc-brd, Noe Antoine, omra-odoo, Zelong Lin, Andrzej(pian), sesn-odoo, Walid (wasa), maad-odoo, aktr-odoo, Aurelien MARIE (auma), Maryam Kia, jorv-odoo, Maxime de Neuville, Matthieu Stockbauer, “Beekan”, Ricardoalso, Adrien Minne (adrm), dhba, Bastien Fafchamps (bafa), adsh-odoo, Tanguy Quéguineur, Alex Kühn, nihp-odoo, adch-odoo, Adnan Saiyed, Chrysanthe (chgo), sami odoo, mano-odoo, Harsh Shah, Joseph (jcb), thle-odoo, guce, Elisabeth Dickinson, Antoine (anso), Mohammed Basioni, Sébastien (blse), sben-odoo, abdelrahmanfawzy, Lucas Lefèvre (lul), Pierre Pulinckx, Anton Romanova (roan), Bastien PIERRE, nikj-odoo, Michaël Mattiello, Corentin Heinix (cohe), pish-odoo, Hoste Patrick, Panagiotis Kyriakou, Thomas Josse (THJO), Krzysztof Magusiak (krma), Ajit Singh, nees-odoo, sagu-odoo, kdes-odoo, Maeva De Keyser (MDEK), utma-odoo, mojem, pajo, bhna-odoo, defl, K Theja (kthe@odoo.com), Ayush Chauhan (aych), Giorgio Tocco (gito), akha, jayp-odoo, Tudor-Calin Panzaru (tupan), Julien Launois (jula), Laetitia (ldau), adip-odoo, Patrick Stooks, dhka-odoo, Jérôme Belpaire, Yagnik ✗ (yagp), ramh, Waleed Elgamal, h4818, Saurabh, Yash Tiwari (Yatiw), Bruno BOI, assh-odoo, Beekoan, livaios, Kevin Gerard (kege), Akash Parmar, Louis, pmah-odoo, nmak-odoo, Julian Heuser, Benoit Socias (bso), Ziri, YoussefM890, abbhi-Odoo, =, Serge Bayet, Omar Khalil (omkha), sbbh-odoo, Julien Segers, abhk-odoo, Séna Nshimiyimana, Atovange, Zachary (zavan), Jason (jaca), Kadam Darji, ibo-odoo, jowes-odoo, Farah (ahmfa), akth-odoo, akus-odoo, MostafaTwfiq, Julien Carion, ELCO, jsum-odoo, karygauss03, Haja Ram, khaj-odoo, chpa-odoo, Oussema Heni, stefanorigano (sri), shmn-odoo, Claire Nguyen (clan), mear-odoo, Dylan Provoost, Mohamed Ayman, Frantisek Binovsky, Haroune Hassine (Hahas), niyp-odoo, Dhrumit Parmar, claireclan, Louis Wicket, Julien Coppin (jucop), Joe VanHorn, Jeremy Bethmont, mva-odoo, Alex Kühn, jmra-odoo, Julien Piron, Lucas Gvasalia, nby, Jean Schoenlaub, Elisabeth Dickinson (edi), Mahiv Ram, Mayur Barad, Dario Liotta (dalio), Julien Coppin, radet-odoo, Alex Kuhn, shrp-odoo, kapat-odoo, edi, radhr-odoo
- Odoo dependencies
- Python dependencies
- None
- System dependencies
- None
- Required by
- analytic, auth_signup, auth_totp_mail, base_automation, base_install_request, calendar, cloud_storage, contacts, crm, data_recycle, digest, event, fleet, gamification, google_gmail, iap_mail, im_livechat, link_tracker, lunch, mail_bot, mail_group, mail_tracking, maintenance, mass_mailing, microsoft_outlook, phone_validation, portal, portal_discuss, privacy_lookup, product, project, queue_job, rating, resource_mail, sales_team, sms, snailmail, survey, test_discuss_full, test_http, test_mail, test_mail_full, test_mail_sms, 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 (151)
| XML ID | Name | Model | Type | Status |
|---|---|---|---|---|
account_security_alert |
Alert Security Update | ir.ui.view | qweb | New |
content_markdown |
Thumbnails / Preview for markdown attachments | ir.ui.view | qweb | New |
content_text |
Thumbnails / Preview for text attachments | ir.ui.view | qweb | New |
discuss_call_history_view_form |
discuss.call.history.view.form | discuss.call.history | form | New |
discuss_call_history_view_search |
discuss.call.history.view.search | discuss.call.history | search | New |
discuss_call_history_view_tree |
discuss.call.history.view.list | discuss.call.history | list | New |
discuss_category_view_form |
discuss.category.form | discuss.category | form | New |
discuss_category_view_kanban |
discuss.category.kanban | discuss.category | kanban | New |
discuss_category_view_search |
discuss.category.search | discuss.category | search | New |
discuss_category_view_tree |
discuss.category.list | discuss.category | 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 | |
group_change_template |
group_change_template | ir.ui.view | qweb | New |
ir_access_form_view_inherit_mail |
ir.access.view.form.inherit.mail | ir.access | form | Inherits base.ir_access_form_view |
ir_attachment_view_list |
ir.attachment.list.inherit.mail | ir.attachment | list | Inherits base.view_attachment_tree |
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 |
ir_ui_view_view_search_mail |
ir.ui.view.view.search.mail | ir.ui.view | search | New |
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_my_conversations_view_search |
discuss.channel.search | discuss.channel | search | 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_graph |
mail.activity.view.graph | mail.activity | graph | New |
mail_activity_view_kanban_open_target |
mail.activity.view.kanban.open.target | mail.activity | kanban | New |
mail_activity_view_pivot |
mail.activity.view.pivot | mail.activity | pivot | 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 |
mail_tracking_template |
mail_tracking_template | ir.ui.view | qweb | 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_config_settings_view_form_sfu_client_source |
res.config.settings.view.form.sfu.client.source | res.config.settings | form | New |
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_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 (20)
| Route(s) | Handler | Auth | Type | Methods | Flags |
|---|---|---|---|---|---|
/mail/attachment/pdf_first_page/<int:attachment_id> |
AttachmentController.mail_attachment_pdf_first_page |
public | http | GET | sudo |
/mail/attachment/render_text/<int:attachment_id> |
AttachmentController.mail_attachment_render_text |
public | http | ALL | |
/discuss/gif/add_favorite |
DiscussGifController.add_favorite |
user | jsonrpc | ALL | sudo |
/discuss/gif/categories |
DiscussGifController.categories |
user | jsonrpc | ALL | sudo |
/discuss/gif/favorites |
DiscussGifController.get_favorites |
user | jsonrpc | ALL | sudo |
/discuss/gif/remove_favorite |
DiscussGifController.remove_favorite |
user | jsonrpc | ALL | sudo |
/discuss/gif/search |
DiscussGifController.search |
user | jsonrpc | ALL | sudo |
| (inherited route override) | Home.web_client |
inherited | http | ALL | |
/mail/font_to_img/<icon>/<font>/<int:fill>/<color>/<bg>/<int:width>x<int:height>fs<int:font_size> |
MailController.export_icon_to_png |
none | http | ALL | |
/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_legacy |
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/rtc/audio_worklet_processor_v2 |
RtcController.audio_worklet_processor |
public | http | GET | |
/mail/rtc/channel/upgrade_connection |
RtcController.channel_upgrade |
user | jsonrpc | POST | sudo |
/mail/rtc/recording/<int:call_history_id>/routing |
RtcController.get_routing |
public | http | POST | csrf off sudo |
/mail/rtc/session/notify_call_members |
RtcController.session_call_notify |
public | jsonrpc | POST | sudo |
/discuss/voice/worklet_processor |
VoiceController.voice_worklet_processor |
public | http | GET | |
| (inherited route override) | WebsocketControllerPresence.peek_notifications |
inherited | http | ALL | |
/websocket/update_bus_presence |
WebsocketControllerPresence.update_bus_presence |
public | jsonrpc | ALL |
Models touched (94)
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.
No new fields.
Public methods (0)No public methods.
No new fields.
Public methods (0)No public methods.
No new fields.
Public methods (0)No public methods.
No new fields.
Public methods (0)No public methods.
No new fields.
Public methods (1)-
write(self, vals)
-
artifact_idsOne2many → mail.call.artifactstring='Artifacts' args: 'mail.call.artifact', 'discuss_call_history_id' -
channel_idMany2one → discuss.channelindex=Trueondelete='cascade'required=True args: 'discuss.channel' -
duration_hourFloatcompute='_compute_duration_hour' -
end_dtDatetime -
has_audioBooleancompute='_compute_recording_media' -
has_recordingBooleancompute='_compute_recording_media' -
has_videoBooleancompute='_compute_recording_media' -
start_call_message_idMany2one → mail.messageindex=True args: 'mail.message' -
start_dtDatetimeindex=Truerequired=True
No public methods.
-
channel_idsOne2many → discuss.channelstring='Channels' args: 'discuss.channel', 'discuss_category_id' -
nameCharrequired=True args: 'Name' -
sequenceIntegerdefault=_default_sequence args: 'Sequence'
No public methods.
-
activeBooleandefault=Truehelp='Set active to false to hide the channel without removing it.' -
avatar_128Imagecompute='_compute_avatar_128'max_height=128max_width=128 args: 'Avatar' -
avatar_cache_keyCharcompute='_compute_avatar_cache_key' -
call_history_idsOne2many → discuss.call.historyargs: 'discuss.call.history', 'channel_id' -
can_joinBooleancompute='_compute_can_join' args: 'Can Join' -
can_leaveBooleancompute='_compute_can_leave' args: 'Can Leave' -
can_self_edit_readonly_channelBooleancompute='_compute_can_self_edit_readonly_channel' -
channel_member_idsOne2many → discuss.channel.memberstring='Members' args: 'discuss.channel.member', 'channel_id' -
channel_name_member_idsOne2many → discuss.channel.membercompute='_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_idsMany2many → res.partnercompute='_compute_channel_partner_ids'inverse='_inverse_channel_partner_ids'search='_search_channel_partner_ids'string='Partners' args: 'res.partner' -
channel_typeSelectiondefault='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=Truerequired=Truestring='Conversation Type' args: [('chat', 'Chat'), ('channel', 'Channel'), ('group', 'Group Chat')] -
default_display_modeSelectionhelp='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' -
descriptionTextargs: 'Description' -
discuss_category_idMany2one → discuss.categoryindex=Trueondelete='set null'string='Category' args: 'discuss.category' -
from_message_idMany2one → mail.messagehelp='The message the channel was created from.'readonly=True args: 'mail.message' -
group_idsMany2many → res.groupshelp='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_idMany2one → res.groupscompute='_compute_group_public_id'readonly=Falserecursive=Truestore=Truestring='Authorized Group' args: 'res.groups' -
image_128Imagemax_height=128max_width=128 args: 'Image' -
invitation_urlCharcompute='_compute_invitation_url' args: 'Invitation URL' -
invited_member_idsOne2many → discuss.channel.membercompute='_compute_invited_member_ids'compute_sudo=True args: 'discuss.channel.member' -
is_editableBooleancompute='_compute_is_editable' args: 'Is Editable' -
is_memberBooleancompute='_compute_is_member'compute_sudo=Truesearch='_search_is_member' args: 'Is Member' -
is_readonlyBooleanhelp='Only admins are allowed to post messages in a read-only channel.' args: 'Read-only' -
last_interest_dtDatetimedefault=<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 Activity' -
meeting_start_dtDatetimecompute='_compute_meeting_dt' args: 'Meeting Start' -
meeting_stop_dtDatetimecompute='_compute_meeting_dt' args: 'Meeting End' -
member_countIntegercompute='_compute_member_count'compute_sudo=Truestring='Member Count' -
member_indicesCharcompute='_compute_member_indices'precompute=Truestore=True -
message_countIntegercompute='_compute_message_count'readonly=True args: '# Messages' -
nameCharrequired=True args: 'Name' -
parent_channel_idMany2one → discuss.channelbypass_search_access=Truehelp='Parent channel'index=Trueondelete='cascade'readonly=True args: 'discuss.channel' -
rtc_session_idsOne2many → discuss.channel.rtc.sessiongroups='base.group_system' args: 'discuss.channel.rtc.session', 'channel_id' -
self_member_idMany2one → discuss.channel.membercompute='_compute_self_member_id'compute_sudo=Truesearch='_search_self_member_id' args: 'discuss.channel.member' -
sfu_channel_uuidChargroups='base.group_system' -
sfu_server_urlChargroups='base.group_system' -
sub_channel_idsOne2many → discuss.channelreadonly=Truestring='Sub Channels' args: 'discuss.channel', 'parent_channel_id' -
uuidCharcopy=Falsedefault=_generate_random_tokensize=50 args: 'UUID'
-
action_reset_invitation_uuid(self) -
action_unfollow(self) -
action_view_recordings(self) -
channel_change_description(self, description) -
channel_join(self)Shortcut to add the current user as member of self channels. If the user is already a member, updates the last_interest_dt. -
channel_rename(self, name) -
create(self, vals_list)@api.model_create_multi -
execute_command_help(self, **kwargs) -
execute_command_who(self, **kwargs) -
get_invite_partner_domain(self)@api.readonlyReturns the domain of the partners that may still be invited to this channel. -
invite_by_email(self, emails)Send channel invitation emails to a list of email addresses. This creates "pending" members until the member has joined the conversation. These "pending" members can have their invitation sent again by email. :param emails: List of email addresses to invite. :type emails: list[str] -
message_post(self, *, message_type='notification', partner_ids=None, **kwargs) -
open_chat_window_action(self)Return an action the web client can use to open this channel. -
set_message_pin(self, message_id, pinned) -
web_read_group(self, domain, groupby, aggregates=(), limit=None, offset=0, order=None, *, auto_unfold=False, opening_info=None, unfold_read_specification=None, unfold_read_default_limit=80, groupby_read_specification=None)@api.model -
write(self, vals)
-
channel_idMany2one → discuss.channelindex=Trueondelete='cascade'required=True args: 'discuss.channel' -
last_interest_dtDatetimerequired=True
No public methods.
-
can_unlinkBooleancompute='_compute_can_unlink' -
channel_idMany2one → discuss.channelbypass_search_access=Trueondelete='cascade'required=True args: 'discuss.channel', 'Channel' -
channel_roleSelectiondefault=Nonegroups='base.group_system'help='The role of the member in the channel. The owner can add and remove admins. The owner and admins can edit the channel and its members.'string='Channel Role' args: [('owner', 'Owner'), ('admin', 'Admin')] -
custom_notificationsSelectionhelp='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' -
guest_idMany2one → mail.guestindex=Trueondelete='cascade' args: 'mail.guest', 'Guest' -
invitation_sent_dtDatetimehelp='Date and time at which the invitation was last sent to this member. Cleared when the member joins, so a value means the invitation is still pending.' args: 'Invitation Sent On' -
is_favoriteBooleanargs: 'Favorite' -
is_pinnedBooleancompute='_compute_is_pinned'search='_search_is_pinned' args: 'Is pinned on the interface' -
is_selfBooleancompute='_compute_is_self'search='_search_is_self' -
is_unreadBooleancompute='_compute_is_unread'compute_sql='_compute_sql_is_unread'compute_sudo=True args: 'Has unread messages' -
last_interest_dtDatetimedefault=<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 Activity' -
last_seen_dtDatetimeargs: 'Last seen date' -
message_unread_counterIntegercompute='_compute_message_unread'compute_sudo=True args: 'Unread Messages Counter' -
mute_until_dtDatetimehelp='If set, the member will not receive notifications from the channel until this date.' args: 'Mute notifications until' -
new_message_separatorIntegerdefault=0help='Message id before which the separator should be displayed'required=True -
partner_idMany2one → res.partnerindex=Trueondelete='cascade' args: 'res.partner', 'Partner' -
rtc_inviting_session_idMany2one → discuss.channel.rtc.sessionstring='Ringing session' args: 'discuss.channel.rtc.session' -
rtc_session_idsOne2many → discuss.channel.rtc.sessioncomodel_name='discuss.channel.rtc.session'inverse_name='channel_member_id'string='RTC Sessions' -
seen_message_idMany2one → mail.messageindex='btree_not_null'string='Last Seen' args: 'mail.message' -
unpin_dtDatetimehelp='Contains the date and time when the channel was unpinned by the user.'index=True args: 'Unpin date'
-
create(self, vals_list)@api.model_create_multi -
unlink(self) -
write(self, vals)
-
channel_idMany2one → discuss.channelindex='btree_not_null'readonly=Truerelated='channel_member_id.channel_id'store=True args: 'discuss.channel' -
channel_member_idMany2one → discuss.channel.memberondelete='cascade'required=True args: 'discuss.channel.member' -
guest_idMany2one → mail.guestrelated='channel_member_id.guest_id' args: 'mail.guest' -
is_camera_onBooleanstring='Is sending user video' -
is_deafBooleanstring='Has disabled incoming sound' -
is_mutedBooleanstring='Is microphone muted' -
is_screen_sharing_onBooleanstring='Is sharing the screen' -
partner_idMany2one → res.partnerindex=Truerelated='channel_member_id.partner_id'store=Truestring='Partner' args: 'res.partner' -
write_dateDatetimeindex=True args: 'Last Updated On'
-
action_disconnect(self) -
create(self, vals_list)@api.model_create_multi -
unlink(self)
-
tenor_gif_idCharrequired=True args: 'GIF id from Tenor'
No public methods.
-
attachment_idMany2one → ir.attachmentbypass_search_access=Truecopy=Falseindex=Trueondelete='cascade' args: 'ir.attachment'
No public methods.
-
activeBooleandefault=True args: 'Active' -
attachBooleandefault=Truehelp='Whether attachments should be downloaded. If not enabled, incoming emails will be stripped of any attachments before being processed' args: 'Keep Attachments' -
configurationTextreadonly=True args: 'Configuration' -
dateDatetimereadonly=Truestring='Last Fetch Date' -
error_dateDatetimehelp='Date of last failure, reset on success.'readonly=Truestring='Last Error Date' -
error_messageTextreadonly=Truestring='Last Error Message' -
is_sslBooleanhelp='Connections are encrypted with SSL/TLS through a dedicated port (default: IMAPS=993, POP3S=995)' args: 'SSL/TLS' -
message_idsOne2many → mail.mailreadonly=Truestring='Messages' args: 'mail.mail', 'fetchmail_server_id' -
nameCharrequired=True args: 'Name' -
object_idMany2one → ir.modelhelp='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' -
originalBooleanhelp='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' -
passwordChar -
portInteger -
priorityIntegerdefault=5help='Defines the order of processing, lower values mean higher priority'readonly=Falsestring='Server Priority' -
scriptChardefault='/mail/static/scripts/odoo-mailgate.py'readonly=True -
serverCharhelp='Hostname or IP of the mail server'readonly=Falsestring='Server Name' -
server_typeSelectiondefault='imap'index=Truerequired=Truestring='Server Type' args: [('imap', 'IMAP Server'), ('pop', 'POP Server'), ('local', 'Local Server')] -
server_type_infoTextcompute='_compute_server_type_info' args: 'Server Type Info' -
stateSelectioncopy=Falsedefault='draft'index=Truereadonly=Truestring='Status' args: [('draft', 'Not Confirmed'), ('done', 'Confirmed')] -
userCharreadonly=Falsestring='Username'
-
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)
-
activeBooleantracking=True -
domainChartracking=True -
operationSelectiontracking=True
No public methods.
-
view_modeSelectionondelete={'activity': 'cascade'}selection_add=[('activity', 'Activity')]
No public methods.
-
activity_date_deadline_rangeIntegercompute='_compute_activity_date_deadline_range'readonly=Falsestore=Truestring='Due In' -
activity_date_deadline_range_typeSelectioncompute='_compute_activity_date_deadline_range_type'readonly=Falsestore=Truestring='Due type' args: [('days', 'Days'), ('weeks', 'Weeks'), ('months', 'Months')] -
activity_noteHtmlreadonly=Falsestore=True args: 'Note' -
activity_plan_has_user_on_demandBooleanrelated='activity_plan_id.has_user_on_demand' -
activity_plan_idMany2one → mail.activity.plancompute='_compute_activity_plan_id'domain="['|', ('res_model', '=', False), ('res_model', '=', model_name)]"readonly=Falsestore=Truestring='Activity Plan' args: 'mail.activity.plan' -
activity_role_idMany2one → res.rolecompute='_compute_activity_role_id'ondelete='restrict'readonly=Falsestore=Truestring='Responsible Role' args: 'res.role' -
activity_summaryCharreadonly=Falsestore=True args: 'Summary' -
activity_type_idMany2one → mail.activity.typecompute='_compute_activity_type_id'domain="['|', ('res_model', '=', False), ('res_model', '=', model_name)]"ondelete='restrict'readonly=Falserelated=Falsesearch=Falsestore=Truestring='Activity Type' args: 'mail.activity.type' -
activity_user_field_nameCharcompute='_compute_activity_user_field_name'readonly=Falsestore=True args: 'User Field' -
activity_user_idMany2one → res.userscompute='_compute_activity_user_id'readonly=Falsestore=Truestring='Responsible' args: 'res.users' -
activity_user_typeSelectioncompute='_compute_activity_user_type'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=Falsestore=Truestring='User Type' args: [('specific', 'Specific User'), ('role', 'Specific Role'), ('generic', 'Dynamic User')] -
crud_model_idMany2onetracking=True -
evaluation_typeSelectiontracking=True -
followers_partner_field_nameCharcompute='_compute_followers_info'readonly=Falsestore=Truestring='Followers Field' -
followers_typeSelectioncompute='_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=Falseselection=[('specific', 'Specific Followers'), ('generic', 'Dynamic Followers')]store=Truestring='Followers Type' -
has_activity_plansBooleancompute='_compute_has_activity_plans' -
link_field_idMany2onetracking=True -
log_note_noteHtmlcompute='_compute_log_note_note'readonly=Falsestore=Truetranslate=True args: 'Internal Note' -
mail_post_autofollowBooleancompute='_compute_mail_post_autofollow'readonly=Falsestore=True args: 'Subscribe Recipients' -
model_idMany2onetracking=True -
nameChartracking=True -
partner_idsMany2many → res.partnercompute='_compute_followers_info'readonly=Falsestore=True args: 'res.partner' -
stateSelectionondelete={'mail_post': 'cascade', 'log_note': 'cascade', 'followers': 'cascade', 'remove_followers': 'cascade', 'next_activity': 'cascade'}selection_add=[('next_activity', 'Create Activity'), ('mail_post', 'Send Message'), ('log_note', 'Log Note'), ('followers', 'Add Followers'), ('remove_followers', 'Remove Followers'), ('code')]tracking=True -
subtype_idsMany2many → mail.message.subtypedefault=<expr>readonly=Falsestore=Truestring='Subscriptions' args: 'mail.message.subtype' -
template_idMany2one → mail.templatecompute='_compute_template_id'domain="[('model_id', '=', model_id)]"ondelete='set null'readonly=Falsestore=True args: 'mail.template', 'Mail Template' -
update_pathChartracking=True -
valueTexttracking=True -
webhook_urlChartracking=True
No public methods.
-
has_thumbnailBooleancompute='_compute_has_thumbnail' -
thumbnailImage
-
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.
-
voice_idsOne2many → discuss.voice.metadataargs: 'discuss.voice.metadata', 'attachment_id'
No public methods.
No new fields.
Public methods (4)-
create(self, vals_list)@api.model_create_multi -
set_bool(self, key, value)@api.model -
set_str(self, key, value)@api.model -
write(self, vals)
-
activeBooleantracking=True -
interval_numberIntegertracking=True -
interval_typeSelectiontracking=True -
priorityIntegertracking=True -
user_idMany2onetracking=True
No public methods.
No new fields.
Public methods (1)-
session_info(self)Override to add the current user data (partner or guest) if applicable.
-
mail_template_idsOne2many → mail.templatecomodel_name='mail.template'inverse_name='mail_server_id'readonly=Truestring='Mail template using this mail server' -
owner_limit_countIntegercopy=False args: 'Owner Limit Count' -
owner_limit_timeDatetimecopy=False args: 'Owner Limit Time' -
owner_user_idMany2one → res.userscopy=False args: 'res.users', 'Owner'
No public methods.
-
is_mail_activityBooleandefault=Falsestring='Has Mail Activity' -
is_mail_blacklistBooleandefault=Falsestring='Has Mail Blacklist' -
is_mail_threadBooleandefault=Falsestring='Has Mail Thread'
-
write(self, vals)
-
trackingIntegerhelp='If set every modification done to this field is tracked. Value is used to order tracking values.'string='Enable Ordered Tracking'
No public methods.
No new fields.
Public methods (0)No public methods.
No new fields.
Public methods (0)No public methods.
-
technical_usageSelectionselection_add=[('mail_post_source', 'Message Post Source')] -
typeSelectionselection_add=[('activity', 'Activity')]
No public methods.
No new fields.
Public methods (0)No public methods.
No new fields.
Public methods (0)No public methods.
No new fields.
Public methods (2)-
get_kpi_summary(self)@api.model -
get_mail_activities_kpi_summary(self)@api.model
-
activeBooleandefault=True -
activity_categorySelectionreadonly=Truerelated='activity_type_id.category' -
activity_decorationSelectionreadonly=Truerelated='activity_type_id.decoration_type' -
activity_plan_idMany2one → mail.activity.plancopy=Falseondelete='set null'string='Plan' args: 'mail.activity.plan' -
activity_template_idMany2one → mail.activity.plan.templateindex='btree_not_null'string='Generated From' args: 'mail.activity.plan.template' -
activity_type_idMany2one → mail.activity.typedefault=_default_activity_typedomain="['|', ('res_model', '=', False), ('res_model', '=', res_model)]"index='btree_not_null'ondelete='restrict'string='Activity Type' args: 'mail.activity.type' -
attachment_idsMany2many → ir.attachmentbypass_search_access=Truestring='Attachments' args: 'ir.attachment', 'activity_attachment_rel', 'activity_id', 'attachment_id' -
automatedBooleanhelp='Indicates this activity has been created automatically and not by any user.'readonly=True args: 'Automated activity' -
can_writeBooleancompute='_compute_can_write' -
date_deadlineDatecompute='_compute_date_deadline'index=Trueprecompute=Truereadonly=Falserequired=Truestore=True args: 'Due Date' -
date_doneDatecompute='_compute_date_done'store=True args: 'Done Date' -
feedbackTextargs: 'Feedback' -
iconCharreadonly=Truerelated='activity_type_id.icon' args: 'Icon' -
mail_template_idsMany2manyreadonly=Truerelated='activity_type_id.mail_template_ids' -
noteHtmlcompute='_compute_note'precompute=Truereadonly=Falsesanitize_style=Truestore=True args: 'Note' -
phoneCharcompute='_compute_phone'readonly=Falsestore=True args: 'Phone' -
res_access_createBooleancompute=<expr>compute_sudo=Truedepends_context=('uid')groups=fields.NO_ACCESSsearch=<expr> -
res_access_readBooleancompute=<expr>compute_sudo=Truedepends_context=('uid')groups=fields.NO_ACCESSsearch=<expr> -
res_access_unlinkBooleancompute=<expr>compute_sudo=Truedepends_context=('uid')groups=fields.NO_ACCESSsearch=<expr> -
res_access_writeBooleancompute=<expr>compute_sudo=Truedepends_context=('uid')groups=fields.NO_ACCESSsearch=<expr> -
res_idMany2oneReferenceindex=Truemodel_field='res_model'string='Related Document ID' -
res_modelCharindex=Trueprecompute=Truereadonly=Truerelated='res_model_id.model'store=True args: 'Related Document Model' -
res_model_idMany2one → ir.modelindex=Trueondelete='cascade'required=False args: 'ir.model', 'Document Model' -
res_model_nameCharrelated='res_model_id.display_name'string='Model' -
res_nameCharcompute='_compute_res_name'compute_sudo=Truereadonly=Truestore=True args: 'Document Name' -
role_idMany2one → res.rolecompute='_compute_role_id'index='btree_not_null'ondelete='set null'precompute=Truereadonly=Falserequired=Falsestore=True args: 'res.role', 'Role' -
stateSelectioncompute='_compute_state' args: [('overdue', 'Overdue'), ('today', 'Today'), ('planned', 'Planned'), ('done', 'Done')], 'State' -
summaryCharcompute='_compute_summary'precompute=Truereadonly=Falsestore=True args: 'Summary' -
technical_usageSelectiondefault='none'help='Technical identifier'readonly=Trueselection=[('none', 'Non Technical')] -
user_idMany2one → res.userscompute='_compute_user_id'index=Trueondelete='cascade'precompute=Truereadonly=Falserequired=Falsestore=True args: 'res.users', 'Assigned to' -
user_tzSelectionrelated='user_id.tz'store=Truestring='Timezone'
-
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.readonlyOpens the related record based on the model and ID, or activity if user has no access to the related record. -
action_reschedule_customdate(self, date_deadline) -
action_reschedule_nextweek(self) -
action_reschedule_today(self) -
action_reschedule_tomorrow(self) -
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.modelGet 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 whether "done" activities are integrated in the aggregated data or not. :returns: a dict with the following keys: * ``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 IDs ordered by closest date (deadline for ongoing activities, and done date for done activities). * ``grouped_activities`` -- ``dict[dict]`` mapping ``res_id -> activity_type_id -> aggregated info``, where the aggregated info contains: * ``count_by_state`` (dict) -- mapping state to count (e.g. ``'planned': 2``); * ``ids`` (list) -- activity IDs for the ``res_id`` and ``activity_type_id``; * ``reporting_date`` (str) -- aggregated date of the related activities, as the oldest deadline of ongoing activities if there are any, or the most recent done date of completed activities; * ``state`` (dict) -- aggregated state of the related activities; * ``user_assigned_ids`` (list) -- activity responsible IDs ordered by closest deadline of the related activities; * ``role_to_assign_ids`` (list) -- role IDs for activities without user_id assigned to them. ordered by closest deadline of the related activities; * ``attachments_info`` (dict) -- information about the attachments, ``{'count': int, 'most_recent_id': int, 'most_recent_name': str}``. :rtype: dict -
unlink(self) -
write(self, vals)
-
activity_date_deadlineDatecompute='_compute_activity_date_deadline'compute_sudo=Falsegroups='base.group_user'readonly=Truesearch='_search_activity_date_deadline'store=False args: 'Next Activity Deadline' -
activity_exception_decorationSelectioncompute='_compute_activity_exception_type'help='Type of the exception activity on record.'search='_search_activity_exception_decoration' args: [('warning', 'Alert'), ('danger', 'Error')] -
activity_exception_iconCharcompute='_compute_activity_exception_type'help='Icon to indicate an exception activity.' args: 'Icon' -
activity_idsOne2many → mail.activitybypass_search_access=Truegroups='base.group_user' args: 'mail.activity', 'res_id', 'Activities' -
activity_plans_idsMany2many → mail.activity.plancompute='_compute_activity_plans_ids'search='_search_activity_plans_ids'string='Activity Plans' args: 'mail.activity.plan' -
activity_stateSelectioncompute='_compute_activity_state'compute_sql='_compute_sql_activity_state'compute_sudo=Falsegroups='base.group_user'help='Status based on activities\nOverdue: Due date is already passed\nToday: Activity date is today\nPlanned: Future activities.'string='Activity State' args: [('overdue', 'Overdue'), ('today', 'Today'), ('planned', 'Planned')] -
activity_summaryChargroups='base.group_user'readonly=Falserelated='activity_ids.summary'search='_search_activity_summary' args: 'Next Activity Summary' -
activity_type_iconCharrelated='activity_ids.icon' args: 'Activity Type Icon' -
activity_type_idMany2one → mail.activity.typegroups='base.group_user'readonly=Falserelated='activity_ids.activity_type_id'search='_search_activity_type_id' args: 'mail.activity.type', 'Next Activity Type' -
activity_user_idMany2one → res.userscompute='_compute_activity_user_id'groups='base.group_user'readonly=Truesearch='_search_activity_user_id' args: 'res.users', 'Responsible User' -
my_activity_date_deadlineDatecompute='_compute_my_activity_date_deadline'compute_sudo=Falsegroups='base.group_user'readonly=Truesearch='_search_my_activity_date_deadline' args: 'My Activity Deadline'
-
action_reschedule_my_next_customdate(self, date_deadline) -
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='', activity_user_id_fname='', **act_values)Schedule activities on each record of the current record set (see `_activity_schedule_create_vals`). -
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.
-
activeBooleandefault=True -
company_idMany2one → res.companyargs: 'res.company' -
has_user_on_demandBooleancompute='_compute_has_user_on_demand' args: 'Has on demand responsible' -
nameCharrequired=True args: 'Name' -
res_modelSelectionhelp='Specify a model if the activity should be specific to a model and not available when managing activities for other models.'required=Trueselection=_get_model_selectionstring='Model' -
res_model_idMany2one → ir.modelcompute='_compute_res_model_id'compute_sudo=Trueondelete='cascade'precompute=Truereadonly=Falserequired=Truestore=Truestring='Applies to' args: 'ir.model' -
steps_countIntegercompute='_compute_steps_count' -
template_idsOne2many → mail.activity.plan.templatecopy=Truestring='Activities' args: 'mail.activity.plan.template', 'plan_id'
No public methods.
-
activity_type_idMany2one → mail.activity.typedefault=<expr>domain="['|', ('res_model', '=', False), '&', ('res_model', '!=', False), ('res_model', '=', parent.res_model)]"index=Trueondelete='restrict'required=True args: 'mail.activity.type', 'Activity Type' -
company_idMany2onerelated='plan_id.company_id' -
delay_countIntegerdefault=0help='Number of days/week/month before executing the action after or before the scheduled plan date.' args: 'Interval' -
delay_fromSelectiondefault='before_plan_date'required=Truestring='Trigger' args: [('before_plan_date', 'Before Plan Date'), ('after_plan_date', 'After Plan Date')] -
delay_unitSelectiondefault='days'help='Unit of delay'required=Truestring='Delay units' args: [('days', 'days'), ('weeks', 'weeks'), ('months', 'months')] -
iconCharreadonly=Truerelated='activity_type_id.icon' args: 'Icon' -
noteHtmlcompute='_compute_note'readonly=Falsestore=True args: 'Note' -
plan_idMany2one → mail.activity.planindex=Trueondelete='cascade'required=Truestring='Plan' args: 'mail.activity.plan' -
res_modelSelectionrelated='plan_id.res_model' -
responsible_idMany2one → res.userscheck_company=Truecompute='_compute_responsible_id'readonly=Falsestore=True args: 'res.users', 'Assigned to' -
responsible_typeSelectioncompute='_compute_responsible_type'default='on_demand'readonly=Falserequired=Truestore=Truestring='Assignment' args: [('on_demand', 'Ask at launch'), ('other', 'Specific User'), ('role', 'Role')] -
role_idMany2one → res.rolecompute='_compute_role_id'readonly=Falsestore=True args: 'res.role', 'Role' -
sequenceIntegerdefault=10 -
suggested_next_type_idMany2onerelated='activity_type_id.suggested_next_type_id'string='Suggested Next Activity' -
summaryCharcompute='_compute_summary'readonly=Falsestore=True args: 'Summary'
No public methods.
-
activity_categorySelectionreadonly=Truerelated='activity_type_id.category' -
activity_role_idMany2one → res.rolecompute='_compute_activity_role_id'readonly=Falsestore=True args: 'res.role', 'Role' -
activity_type_available_idsMany2many → mail.activity.typecompute='_compute_activity_type_available_ids'compute_sudo=True args: 'mail.activity.type' -
activity_type_idMany2one → mail.activity.typecompute='_compute_activity_type_id'domain="['|', ('res_model', '=', False), ('res_model', '=', res_model)]"ondelete='set null'readonly=Falsestore=Truestring='Activity Type' args: 'mail.activity.type' -
activity_user_idMany2one → res.userscompute='_compute_activity_user_id'readonly=Falsestore=True args: 'res.users', 'Assigned to' -
activity_user_id_fnameCharhelp='Field name of the user to choose on the record' args: 'User Field' -
company_idMany2one → res.companycompute='_compute_company_id'required=False args: 'res.company', 'Company' -
date_deadlineDatecompute='_compute_date_deadline'readonly=Falsestore=True args: 'Due Date' -
errorHtmlcompute='_compute_error' -
has_errorBooleancompute='_compute_error' -
has_warningBooleancompute='_compute_error' -
is_batch_modeBooleancompute='_compute_is_batch_mode' args: 'Use in batch' -
noteHtmlcompute='_compute_note'readonly=Falsesanitize_style=Truestore=True args: 'Note' -
phoneCharcompute='_compute_phone'compute_sudo=Falsereadonly=Falsestore=True args: 'Phone' -
plan_available_idsMany2many → mail.activity.plancompute='_compute_plan_available_ids'compute_sudo=Truestore=True args: 'mail.activity.plan' -
plan_dateDatecompute='_compute_plan_date'readonly=Falsestore=True args: 'Plan Date' -
plan_has_user_on_demandBooleanrelated='plan_id.has_user_on_demand' -
plan_idMany2one → mail.activity.plancompute='_compute_plan_id'domain="[('id', 'in', plan_available_ids)]"readonly=Falsestore=True args: 'mail.activity.plan' -
plan_on_demand_role_idMany2one → res.rolehelp='Choose assignation for activities with on demand assignation.' args: 'res.role', 'Assigned Role' -
plan_on_demand_user_idMany2one → res.usersdefault=<expr>help='Choose assignation for activities with on demand assignation.' args: 'res.users', 'Assigned To' -
plan_schedule_line_idsOne2many → mail.activity.schedule.linecompute='_compute_plan_schedule_line_ids'string='Schedule Lines' args: 'mail.activity.schedule.line', 'activity_schedule_id' -
res_idsTextcompute='_compute_res_ids'precompute=Truereadonly=Falsestore=True args: 'Document IDs' -
res_modelCharreadonly=Falserequired=False args: 'Model' -
res_model_idMany2one → ir.modelcompute='_compute_res_model_id'compute_sudo=Trueondelete='cascade'precompute=Truereadonly=Falserequired=Falsestore=Truestring='Applies to' args: 'ir.model' -
summaryCharcompute='_compute_summary'readonly=Falsestore=True args: 'Summary' -
warningHtmlcompute='_compute_error'
-
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.modelReturn a list of valid models for a user to define an activity on.
-
activity_schedule_idMany2one → mail.activity.scheduleondelete='cascade'required=Truestring='Activity Schedule' args: 'mail.activity.schedule' -
line_date_deadlineDateargs: 'Date Deadline' -
line_descriptionCharargs: 'Line Description' -
responsible_user_idMany2one → res.usersstring='Responsible User' args: 'res.users' -
role_idMany2one → res.rolestring='Role' args: 'res.role'
No public methods.
-
activeBooleandefault=True -
categorySelectiondefault='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')] -
create_uidMany2one → res.usersindex=True args: 'res.users' -
decoration_typeSelectionhelp='Change the background color of the related activities of this type.'string='Decoration Type' args: [('warning', 'Alert'), ('danger', 'Error')] -
default_noteHtmlstring='Default Note'translate=True -
default_role_idMany2one → res.rolestring='Role' args: 'res.role' -
default_user_idMany2one → res.usersstring='Default User' args: 'res.users' -
delay_countIntegerdefault=0help='Number of days/week/month before executing the action. It allows to plan the action deadline.' args: 'Schedule' -
delay_fromSelectiondefault='previous_activity'help='Type of delay'required=Truestring='Delay Type' args: [('current_date', 'after previous activity completion date'), ('previous_activity', 'after previous activity deadline')] -
delay_labelCharcompute='_compute_delay_label' -
delay_unitSelectiondefault='days'help='Unit of delay'required=Truestring='Delay units' args: [('days', 'days'), ('weeks', 'weeks'), ('months', 'months')] -
iconCharhelp='Material Symbols icon e.g. checklist' args: 'Icon' -
initial_res_modelSelectioncompute='_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_selectionstore=Falsestring='Initial model' -
kpi_provider_visibilitySelectiondefault='own'help='Whether this type of activity should be displayed in the KPI Provider API.\nNone: never display this type of activity\nOwn Activities: the synchronization user will only count their own activities of this type\nAll Activities: the synchronization user will count all the activities of this type, whatever their owner'string='KPI Provider Visibility' args: [('none', 'None'), ('own', 'Own Activities'), ('all', 'All Activities')] -
mail_template_idsMany2many → mail.templatestring='Email templates' args: 'mail.template' -
nameCharrequired=Truetranslate=True args: 'Name' -
previous_type_idsMany2many → mail.activity.typedomain="['|', ('res_model', '=', False), ('res_model', '=', res_model)]"string='Preceding Activities' args: 'mail.activity.type', 'mail_activity_rel', 'recommended_id', 'activity_id' -
res_modelSelectionhelp='Specify a model if the activity should be specific to a model and not available when managing activities for other models.'selection=_get_model_selectionstring='Model' -
res_model_changeBooleandefault=Falsestore=Falsestring='Model has change' -
sequenceIntegerdefault=10 args: 'Sequence' -
suggested_next_type_idMany2one → mail.activity.typedomain="['|', ('res_model', '=', False), ('res_model', '=', res_model)]"help='Suggest this activity once the current one is marked as done.'string='Suggest Next Activity' args: 'mail.activity.type' -
summaryChartranslate=True args: 'Default Summary'
-
action_archive(self) -
unlink(self)When removing an activity type, put activities into a Todo. -
write(self, vals)
-
alias_bounced_contentHtmlhelp='If set, this content will automatically be sent out to unauthorized users instead of the default message.'translate=True args: 'Custom Bounced Message' -
alias_contactSelectiondefault='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=Truestring='Alias Contact Security' args: [('everyone', 'Everyone'), ('partners', 'Authenticated Partners'), ('followers', 'Followers only')] -
alias_defaultsTextdefault='{}'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_domainCharrelated='alias_domain_id.name' args: 'Alias domain name' -
alias_domain_idMany2one → mail.alias.domaindefault=<expr>ondelete='restrict'string='Alias Domain' args: 'mail.alias.domain' -
alias_force_thread_idIntegerhelp='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_nameCharcompute='_compute_alias_full_name'index='btree_not_null'store=True args: 'Alias Email' -
alias_incoming_localBooleandefault=False args: 'Local-part based incoming detection' -
alias_model_idMany2one → ir.modeldomain="[('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_nameCharcopy=Falsehelp="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_idMany2one → ir.modelhelp='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_idIntegerhelp='ID of the parent record holding the alias (example: project holding the task creation alias)' args: 'Parent Record Thread ID' -
alias_statusSelectioncompute='_compute_alias_status'help='Alias status assessed on the last message received.'store=True args: [('not_tested', 'Not Tested'), ('valid', 'Valid'), ('invalid', 'Invalid')]
-
create(self, vals_list)@api.model_create_multiCreates 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).
-
bounce_aliasChardefault='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_emailCharcompute='_compute_bounce_email' args: 'Bounce Email' -
catchall_aliasChardefault='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_emailCharcompute='_compute_catchall_email' args: 'Catchall Email' -
company_idsOne2many → res.companyhelp='Companies using this domain as default for sending mails'string='Companies' args: 'res.company', 'alias_domain_id' -
default_fromChardefault='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_emailCharcompute='_compute_default_from_email' args: 'Default From' -
nameCharcopy=Truehelp="Email domain e.g. 'example.com' in 'odoo@example.com'"required=True args: 'Name' -
sequenceIntegerdefault=10
-
create(self, vals_list)@api.model_create_multiSanitize bounce_alias / catchall_alias / default_from -
write(self, vals)Sanitize name / bounce_alias / catchall_alias / default_from
-
alias_defaultsTextinherited=True -
alias_idMany2oneindex=Trueinit_storage=<expr>required=True -
alias_nameCharinherited=True
No public methods.
-
alias_defaultsTextrelated='alias_id.alias_defaults' -
alias_domainCharrelated='alias_id.alias_domain' args: 'Alias Domain Name' -
alias_domain_idMany2one → mail.alias.domainreadonly=Falserelated='alias_id.alias_domain_id'string='Alias Domain' args: 'mail.alias.domain' -
alias_emailCharcompute='_compute_alias_email'search='_search_alias_email' args: 'Email Alias' -
alias_idMany2one → mail.aliascopy=Falseindex='btree_not_null'ondelete='restrict'required=Falsestring='Alias' args: 'mail.alias' -
alias_nameCharreadonly=Falserelated='alias_id.alias_name'
-
copy_data(self, default=None) -
create(self, vals_list)@api.model_create_multiCreate 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.
-
activeBooleandefault=Truetracking=2 -
emailCharhelp='This field is case insensitive.'index='trigram'required=Truestring='Email Address'tracking=1
-
action_add(self) -
create(self, vals_list)@api.model_create_multi -
mail_action_blacklist_remove(self) -
write(self, vals)
-
emailCharname='Email'readonly=Truerequired=True -
reasonCharname='Reason'
-
action_unblacklist_apply(self)
-
discuss_call_history_idMany2one → discuss.call.historyindex=Trueondelete='cascade'required=Falsestring='Discuss Call History' args: 'discuss.call.history' -
end_msIntegerdefault=0help='Offset from the start of the call in milliseconds'required=Truestring='End (ms)' -
media_idMany2one → ir.attachmentcompute='_compute_media_id'string='Media Attachment' args: 'ir.attachment' -
recording_started_by_idMany2one → res.usersondelete='set null'readonly=Truestring='Recording Started By' args: 'res.users' -
recording_upload_pendingBooleancopy=False -
start_msIntegerdefault=0help='Offset from the start of the call in milliseconds'required=Truestring='Start (ms)'
No public methods.
-
group_idsMany2many → res.groupsdomain=<expr>falsy_value_label=_lt('🔒 Private')string='Authorized Groups' args: 'res.groups' -
is_editableBooleancompute='_compute_is_editable'string='Determines if the canned response can be edited by the current user' -
is_sharedBooleancompute='_compute_is_shared'store=Truestring='Determines if the canned_response is currently shared with other users' -
last_usedDatetimehelp='Last time this canned_response was used' args: 'Last Used' -
sourceCharcopy=mark_as_copy('source')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' -
substitutionTexthelp='Content that will automatically replace the shortcut of your choosing. This content can still be adapted before sending your message.'required=True args: 'Substitution'
-
create(self, vals_list)@api.model_create_multi -
unlink(self) -
write(self, vals)
-
attachment_idsMany2many → ir.attachmentbypass_search_access=Truecompute='_compute_attachment_ids'readonly=Falsestore=Truestring='Attachments' args: 'ir.attachment', 'mail_compose_message_ir_attachments_rel', 'wizard_id', 'attachment_id' -
attachment_linksHtmlcompute='_compute_attachment_links' args: 'Attachment links' -
attachment_links_infoCharcompute='_compute_attachment_links' -
author_idMany2one → res.partnercompute='_compute_authorship'compute_sudo=Falsehelp='Author of the message. If not set, email_from may hold an email address that did not match any partner.'readonly=Falsestore=Truestring='Author' args: 'res.partner' -
auto_deleteBooleancompute='_compute_auto_delete'compute_sudo=Falsehelp="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=Falsestore=True args: 'Delete Emails' -
auto_delete_keep_logBooleancompute='_compute_auto_delete_keep_log'help='Keep a copy of the email content if emails are removed (mass mailing only)'readonly=Falsestore=True args: 'Keep Message Copy' -
bodyHtmlcompute='_compute_body'readonly=Falserender_engine='qweb'render_options={'post_process': True}sanitize_style=Truestore=True args: 'Contents' -
composition_batchBooleancompute='_compute_composition_batch' args: 'Batch composition' -
composition_comment_optionSelectionstring='Comment Options' args: [('reply_all', 'Reply-All'), ('forward', 'Forward')] -
composition_modeSelectiondefault='comment'selection=[('comment', 'Post on a document'), ('mass_mail', 'Email Mass Mailing')]string='Composition mode' -
email_add_signatureBooleancompute='_compute_email_add_signature'readonly=Falsestore=True args: 'Add signature' -
email_fromCharcompute='_compute_authorship'compute_sudo=Falsehelp='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=Falsestore=True args: 'From' -
email_layout_xmlidCharcompute='_compute_email_layout_xmlid'compute_sudo=Falsecopy=Falsereadonly=Falsestore=True args: 'Email Notification Layout' -
email_notification_allow_headerBooleandefault=True -
force_sendBooleancompute='_compute_force_send'readonly=Falsestore=True args: 'Send mailing or notifications directly' -
mail_activity_type_idMany2one → mail.activity.typeondelete='set null' args: 'mail.activity.type', 'Mail Activity Type' -
mail_server_idMany2one → ir.mail_servercompute='_compute_mail_server_id'compute_sudo=Falsereadonly=Falsestore=Truestring='Outgoing mail server' args: 'ir.mail_server' -
message_typeSelectiondefault='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' -
modelCharcompute='_compute_model'readonly=Falsestore=True args: 'Related Document Model' -
model_is_threadBooleancompute='_compute_model_is_thread' args: 'Thread-Enabled' -
notified_bcc_contains_shareBooleancompute='_compute_notified_bcc_contains_share' args: 'Is an external partner follower of the document?' -
notify_authorBooleancompute='_compute_notify_author'readonly=Falsestore=True -
notify_author_mentionBooleancompute='_compute_notify_author_mention'readonly=Falsestore=True -
notify_skip_followersBooleancompute='_compute_notify_skip_followers'readonly=Falsestore=True -
parent_idMany2one → mail.messageondelete='set null' args: 'mail.message', 'Parent Message' -
partner_cc_allowedBooleancompute='_compute_partner_cc_allowed'readonly=Falsestore=True args: 'Cc Usage Allowed' -
partner_cc_idsMany2many → res.partnercompute='_compute_recipient_partners'readonly=Falsestore=True args: 'res.partner', 'mail_compose_message_res_partner_cc_rel', 'wizard_id', 'partner_id', 'Additional Cc contacts' -
partner_idsMany2many → res.partnercompute='_compute_recipient_partners'readonly=Falsestore=True args: 'res.partner', 'mail_compose_message_res_partner_rel', 'wizard_id', 'partner_id', 'Additional Contacts' -
partner_ids_all_have_emailBooleancompute='_compute_partner_ids_all_have_email' -
record_alias_domain_idMany2one → mail.alias.domaincompute='_compute_record_environment'readonly=Falsestore=True args: 'mail.alias.domain', 'Alias Domain' -
record_company_idMany2one → res.companycompute='_compute_record_environment'readonly=Falsestore=True args: 'res.company', 'Company' -
reply_toCharcompute='_compute_reply_to'compute_sudo=Falsehelp='Reply email address. Setting the reply_to bypasses the automatic thread creation.'readonly=Falsestore=True args: 'Reply To' -
reply_to_force_newBooleancompute='_compute_reply_to_force_new'help='Manage answers as new incoming emails instead of replies going to the same thread.'readonly=Falsestore=Truestring='Considers answers as new thread' -
reply_to_modeSelectioncompute='_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_domainTextargs: 'Active domain' -
res_domain_user_idMany2one → res.usershelp='Used as context used to evaluate composer domain'string='Responsible' args: 'res.users' -
res_idsTextcompute='_compute_res_ids'readonly=Falsestore=True args: 'Related Document IDs' -
scheduled_dateCharcompute='_compute_scheduled_date'compute_sudo=Falsehelp='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=Falsestore=True args: 'Scheduled Date' -
subjectCharcompute='_compute_subject'readonly=Falsestore=True args: 'Subject' -
subject_placeholderCharcompute='_compute_subject_placeholder' args: 'Subject Placeholder' -
subtype_idMany2one → mail.message.subtypecompute='_compute_subtype_id'ondelete='set null'readonly=Falsestore=True args: 'mail.message.subtype', 'Subtype' -
subtype_is_logBooleancompute='_compute_subtype_is_log' args: 'Is a log' -
template_idMany2one → mail.templatedomain="[('model', '=', model), '|', ('user_id','=', False), ('user_id', '=', uid)]" args: 'mail.template', 'Use template' -
template_nameCharargs: 'Template Name' -
use_exclusion_listBooleancopy=Falsedefault=Truehelp='Prevent sending messages to blacklisted contacts. Disable only when absolutely necessary.' args: 'Use Exclusion List'
-
action_schedule_message(self) -
action_send_mail(self)Used for action button that do not accept arguments. -
action_update_message(self) -
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.modelHandle 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.
-
bodyHtmlcompute='_compute_body'compute_sudo=Falsereadonly=Falserender_engine='qweb'render_options={'post_process': True}sanitize='email_outgoing'store=True args: 'Contents' -
body_has_template_valueBooleancompute='_compute_body_has_template_value' args: 'Body content is the same as the template' -
can_edit_bodyBooleancompute='_compute_can_edit_body' args: 'Can Edit Body' -
is_mail_template_editorBooleancompute='_compute_is_mail_template_editor' args: 'Is Editor' -
langCharcompute='_compute_lang'compute_sudo=Falseprecompute=Truereadonly=Falsestore=True -
subjectCharcompute='_compute_subject'compute_sudo=Falsereadonly=Falsestore=True args: 'Subject' -
template_idMany2one → mail.templatedomain="[('model', '=', render_model)]" args: 'mail.template', 'Mail Template'
No public methods.
-
emailCharrelated='partner_id.email' args: 'Email' -
is_activeBooleanrelated='partner_id.active' args: 'Is Active' -
nameCharrelated='partner_id.name' args: 'Name' -
partner_idMany2one → res.partnerindex=Trueondelete='cascade'required=Truestring='Related Partner' args: 'res.partner' -
res_idMany2oneReferencehelp='Id of the followed resource'index=Truemodel_field='res_model' args: 'Related Document ID' -
res_modelCharindex=Truerequired=True args: 'Related Document Model Name' -
subtype_idsMany2many → mail.message.subtypehelp="Message subtypes followed, meaning subtypes that will be pushed onto the user's Wall."string='Subtype' args: 'mail.message.subtype'
No public methods.
-
messageHtmlargs: 'Message' -
notifyBooleandefault=False args: 'Notify Recipients' -
operationSelectiondefault='add'required=Truestring='Operation' args: [('add', 'Add'), ('remove', 'Remove')] -
partner_idsMany2many → res.partnerrequired=Truestring='Followers' args: 'res.partner' -
res_idsCharhelp='Ids of the followed resources' args: 'Related Document IDs' -
res_modelCharhelp='Model of the followed resource'required=True args: 'Related Document Model'
-
edit_followers(self)
-
emailCharrequired=True args: 'Email Address' -
email_normalizedCharcompute='_compute_email_normalized'index=Truestore=Truestring='Normalized Email'
-
get_empty_list_help(self, help_message)@api.model
-
access_tokenCharcopy=Falsedefault=<expr>groups='base.group_system'readonly=Truerequired=Truestring='Access Token' -
channel_idsMany2many → discuss.channelcolumn1='guest_id'column2='channel_id'comodel_name='discuss.channel'copy=Falserelation='discuss_channel_member'string='Channels' -
country_idMany2one → res.countrycomodel_name='res.country'string='Country' -
emailChar -
im_statusSelectioncompute='_compute_im_status'compute_sudo=True args: [('online', 'Online'), ('away', 'Away'), ('offline', 'Offline')], 'IM Status' -
langSelectionselection=_lang_getstring='Language' -
nameCharrequired=Truestring='Name' -
offline_sinceDatetimecompute='_compute_im_status'compute_sudo=True args: 'Offline since' -
presence_idsOne2many → mail.presencegroups='base.group_system' args: 'mail.presence', 'guest_id' -
timezoneSelectionselection=_tz_getstring='Timezone'
No public methods.
-
credentialChar -
server_typeSelectiondefault='stun'required=Truestring='Type' args: [('stun', 'stun:'), ('turn', 'turn:')] -
uriCharrequired=True args: 'URI' -
usernameChar
No public methods.
-
create_dateDatetimeindex=True -
image_mimetypeCharargs: 'Image MIME type' -
message_link_preview_idsOne2many → mail.message.link.previewgroups='base.group_erp_manager' args: 'mail.message.link.preview', 'link_preview_id' -
og_descriptionTextargs: 'Description' -
og_imageCharargs: 'Image' -
og_mimetypeCharargs: 'MIME type' -
og_site_nameCharargs: 'Site name' -
og_titleCharargs: 'Title' -
og_typeCharargs: 'Type' -
source_urlCharrequired=True args: 'URL'
No public methods.
-
auto_deleteBooleanhelp="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_contentHtmlcompute='_compute_body_content'sanitize=Truesearch='_search_body_content' args: 'Rich-text Contents' -
body_htmlTexthelp='Rich-text/HTML message' args: 'Text Contents' -
email_ccCharhelp='Carbon copy message recipients' args: 'Cc' -
email_toTexthelp='Message recipients (emails)' args: 'To' -
failure_reasonTextcopy=Falsehelp='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_typeSelectionselection=[('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_idMany2one → fetchmail.serverindex='btree_not_null'readonly=True args: 'fetchmail.server', 'Inbound Mail Server' -
headersTextcopy=False args: 'Headers' -
is_notificationBooleanhelp='Mail has been created to notify people of an existing mail.message' args: 'Notification Email' -
mail_message_idMany2one → mail.messagebypass_search_access=Trueindex=Trueondelete='cascade'required=True args: 'mail.message', 'Message' -
mail_message_id_intIntegercompute='_compute_mail_message_id_int'compute_sudo=True -
message_typeSelectiondefault='email_outgoing'inherited=Truerelated='mail_message_id.message_type' -
recipient_cc_idsMany2many → res.partnercontext={'active_test': False}relation='mail_mail_res_partner_cc_rel'string='Cc (Partners)' args: 'res.partner' -
recipient_idsMany2many → res.partnercontext={'active_test': False}string='To (Partners)' args: 'res.partner' -
referencesTexthelp='Message references, such as identifiers of previous messages'readonly=True args: 'References' -
restricted_attachment_countIntegercompute='_compute_restricted_attachments' args: 'Restricted attachments' -
scheduled_dateDatetimehelp='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' -
stateSelectioncopy=Falsedefault='outgoing'readonly=True args: [('outgoing', 'Outgoing'), ('sent', 'Sent'), ('received', 'Received'), ('exception', 'Delivery Failed'), ('cancel', 'Cancelled')], 'Status' -
unrestricted_attachment_idsMany2many → ir.attachmentcompute='_compute_restricted_attachments'inverse='_inverse_unrestricted_attachment_ids'string='Unrestricted Attachments' args: 'ir.attachment'
-
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.modelSend 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)
-
attachment_idsMany2many → ir.attachmentbypass_search_access=Truestring='Attachments' args: 'ir.attachment', 'message_attachment_rel', 'message_id', 'attachment_id' -
author_avatarBinarydepends=['author_id']readonly=Falserelated='author_id.avatar_128' args: "Author's avatar" -
author_guest_idMany2one → mail.guestcomodel_name='mail.guest'string='Guest' -
author_idMany2one → res.partnerhelp='Author of the message. If not set, email_from may hold an email address that did not match any partner.'index=Trueondelete='set null' args: 'res.partner', 'Author' -
bodyHtmldefault=''sanitize_style=True args: 'Contents' -
bookmarked_partner_idsMany2many → res.partnerstring='Bookmarked By' args: 'res.partner', 'mail_message_res_partner_bookmarked_rel' -
child_idsOne2many → mail.messageargs: 'mail.message', 'parent_id', 'Child Messages' -
dateDatetimedefault=fields.Datetime.now args: 'Date' -
email_add_signatureBooleandefault=True -
email_fromCharhelp='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_xmlidCharcopy=False args: 'Layout' -
ended_poll_idsOne2many → mail.pollargs: 'mail.poll', 'end_message_id' -
has_errorBooleancompute='_compute_has_error'search='_search_has_error' args: 'Has error' -
has_pollBooleancompute='_compute_has_poll'compute_sudo=True -
incoming_email_ccCharargs: 'Emails Cc' -
incoming_email_toTextargs: 'Emails To' -
is_bookmarkedBooleancompute='_compute_is_bookmarked'help='Current user has bookmarked this message'search='_search_is_bookmarked' args: 'Bookmarked' -
is_current_user_or_guest_authorBooleancompute='_compute_is_current_user_or_guest_author' -
is_internalBooleanhelp='Hide to public / portal users, independently from subtype configuration.' args: 'Employee Only' -
linked_message_idsMany2many → mail.messagecompute='_compute_linked_message_ids' args: 'mail.message' -
mail_activity_type_idMany2one → mail.activity.typeindex='btree_not_null'ondelete='set null' args: 'mail.activity.type', 'Mail Activity Type' -
mail_idsOne2many → mail.mailgroups='base.group_system'string='Mails' args: 'mail.mail', 'mail_message_id' -
mail_server_idMany2one → ir.mail_serverargs: 'ir.mail_server', 'Outgoing mail server' -
message_idCharcopy=Falsehelp='Message unique identifier'index='btree'readonly=True args: 'Message-Id' -
message_link_preview_idsOne2many → mail.message.link.previewgroups='base.group_erp_manager' args: 'mail.message.link.preview', 'message_id' -
message_typeSelectiondefault='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'), ('tracking', 'Tracking')], 'Type' -
modelCharargs: 'Related Document Model' -
needactionBooleancompute='_compute_needaction'search='_search_needaction' args: 'Need Action' -
notification_idsOne2many → mail.notificationbypass_search_access=Truecopy=Falsedepends=['notified_partner_ids'] args: 'mail.notification', 'mail_message_id', 'Notifications' -
notified_partner_idsMany2many → res.partnercontext={'active_test': False}copy=Falsedepends=['notification_ids']string='Partners with Need Action' args: 'res.partner', 'mail_notification' -
outgoing_email_toCharargs: 'emails To' -
parent_idMany2one → mail.messageindex='btree_not_null'ondelete='set null' args: 'mail.message', 'Parent Message' -
partner_cc_idsMany2many → res.partnercontext={'active_test': False}relation='mail_message_res_partner_cc_rel'string='Recipients (Cc)' args: 'res.partner' -
partner_idsMany2many → res.partnercontext={'active_test': False}string='Recipients (To)' args: 'res.partner' -
pinned_atDatetimehelp='Datetime at which the message has been pinned' args: 'Pinned' -
previewCharcompute='_compute_preview'help='The text-only beginning of the body used as email preview.' args: 'Preview' -
reaction_idsOne2many → mail.message.reactiongroups='base.group_system'string='Reactions' args: 'mail.message.reaction', 'message_id' -
record_alias_domain_idMany2one → mail.alias.domainondelete='set null' args: 'mail.alias.domain', 'Alias Domain' -
record_company_idMany2one → res.companyondelete='set null' args: 'res.company', 'Company' -
record_nameCharcompute='_compute_record_name'store=False args: 'Message Record Name' -
reply_toCharhelp='Reply email address. Setting the reply_to bypasses the automatic thread creation.' args: 'Reply-To' -
reply_to_force_newBooleanhelp='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_access_createBooleancompute=<expr>compute_sudo=Truedepends_context=('uid')groups=fields.NO_ACCESSsearch=<expr> -
res_access_readBooleancompute=<expr>compute_sudo=Truedepends_context=('uid')groups=fields.NO_ACCESSsearch=<expr> -
res_access_unlinkBooleancompute=<expr>compute_sudo=Truedepends_context=('uid')groups=fields.NO_ACCESSsearch=<expr> -
res_access_writeBooleancompute=<expr>compute_sudo=Truedepends_context=('uid')groups=fields.NO_ACCESSsearch=<expr> -
res_idMany2oneReferencemodel_field='model' args: 'Related Document ID' -
started_poll_idsOne2many → mail.pollargs: 'mail.poll', 'start_message_id' -
subjectCharargs: 'Subject' -
subtype_idMany2one → mail.message.subtypeindex=Trueondelete='set null' args: 'mail.message.subtype', 'Subtype'
-
action_open_document(self)Opens the related record based on the model and ID -
create(self, vals_list)@api.model_create_multi -
default_get(self, fields)@api.model -
export_data(self, fields_to_export) -
mark_all_as_read(self, domain=None)@api.model -
mark_as_unread(self)Sets the needaction on the messages for the current partner -
set_message_done(self)Remove the needaction from messages for the current partner. -
unlink(self) -
write(self, vals)
-
call_history_idsOne2many → discuss.call.historyargs: 'discuss.call.history', 'start_call_message_id' -
channel_idMany2one → discuss.channelcompute='_compute_channel_id' args: 'discuss.channel'
No public methods.
-
author_idMany2onerelated='message_id.author_id' -
is_hiddenBoolean -
link_preview_idMany2one → mail.link.previewindex=Trueondelete='cascade'required=True args: 'mail.link.preview' -
message_idMany2one → mail.messageindex=Trueondelete='cascade'required=True args: 'mail.message' -
sequenceIntegerargs: 'Sequence'
No public methods.
-
contentCharreadonly=Truerequired=Truestring='Content' -
guest_idMany2one → mail.guestcomodel_name='mail.guest'ondelete='cascade'readonly=Truestring='Reacting Guest' -
message_idMany2one → mail.messagecomodel_name='mail.message'index=Trueondelete='cascade'readonly=Truerequired=Truestring='Message' -
partner_idMany2one → res.partnercomodel_name='res.partner'ondelete='cascade'readonly=Truestring='Reacting Partner'
No public methods.
-
mail_message_idMany2one → mail.messageondelete='cascade'required=Truestring='Message' args: 'mail.message' -
notification_parametersTextargs: 'Notification Parameter' -
scheduled_datetimeDatetimehelp='Datetime at which notification should be sent.'required=True args: 'Scheduled Send Date'
-
create(self, vals_list)@api.model_create_multi -
force_send(self)Launch notification process independently from the expected date.
-
defaultBooleandefault=Truehelp='Activated by default when subscribing.' args: 'Default' -
descriptionTexthelp='Description that will be added in the message posted for this subtype. If void, the name will be added instead.'prefetch=Truetranslate=True args: 'Description' -
hiddenBooleanhelp='Hide the subtype in the follower options' args: 'Hidden' -
internalBooleanhelp='Messages with internal subtypes will be visible only by employees, aka members of base_user group' args: 'Internal Only' -
nameCharhelp='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=Truetranslate=True args: 'Message Type' -
parent_idMany2one → mail.message.subtypehelp='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_fieldCharhelp='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_modelCharhelp='Model the subtype applies to. If False, this subtype applies to all models.' args: 'Model' -
sequenceIntegerdefault=1help='Used to order subtypes.' args: 'Sequence' -
track_recipientsBooleanhelp='Whether to display all the recipients or only the important ones.' args: 'Track Recipients'
-
default_subtypes(self, model_name)@api.modelRetrieve the default subtypes (all, internal, external) for the given model. -
write(self, vals)
-
bodyHtmlhelp='String received from the translation request.'required=Truesanitize_style=True args: 'Translation Body' -
create_dateDatetimeindex=True -
message_idMany2one → mail.messageondelete='cascade'required=True args: 'mail.message', 'Message' -
source_langCharhelp='Result of the language detection based on its content.'required=True args: 'Source Language' -
target_langCharhelp='Shortened language code used as the target for the translation request.'required=True args: 'Target Language'
No public methods.
-
author_idMany2one → res.partnerondelete='set null' args: 'res.partner', 'Author' -
failure_reasonTextcopy=False args: 'Failure reason' -
failure_typeSelectionselection=[('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_readBooleanindex=True args: 'Is Read' -
mail_email_addressChargroups='base.group_user'help='Recipient email address' -
mail_mail_idMany2one → mail.mailhelp='Optional mail_mail ID. Used mainly to optimize searches.'index=True args: 'mail.mail', 'Mail' -
mail_message_idMany2one → mail.messageindex=Trueondelete='cascade'required=True args: 'mail.message', 'Message' -
notification_statusSelectiondefault='ready'index=Truestring='Status' args: [('ready', 'Ready to Send'), ('process', 'Processing'), ('pending', 'Sent'), ('sent', 'Delivered'), ('bounce', 'Bounced'), ('exception', 'Exception'), ('canceled', 'Cancelled')] -
notification_typeSelectiondefault='inbox'index=Truerequired=Truestring='Notification Type' args: [('inbox', 'Inbox'), ('email', 'Email')] -
read_dateDatetimecopy=False args: 'Read Date' -
res_partner_idMany2one → res.partnerindex=Trueondelete='cascade' args: 'res.partner', 'Recipient'
-
create(self, vals_list)@api.model_create_multi -
format_failure_reason(self) -
write(self, vals)
-
allow_multiple_optionsBoolean -
end_message_idMany2one → mail.messageindex=Trueondelete='cascade' args: 'mail.message' -
option_idsOne2many → mail.poll.optionrequired=True args: 'mail.poll.option', 'poll_id' -
poll_end_dtDatetimeindex=True -
poll_questionCharrequired=True -
start_message_idMany2one → mail.messageindex=Trueondelete='cascade'required=True args: 'mail.message' -
winning_option_idMany2one → mail.poll.optioncompute='_compute_winning_option_ids' args: 'mail.poll.option'
No public methods.
-
number_of_votesIntegercompute='_compute_number_of_votes' -
option_emojiCharhelp='Emoji of the poll option'string='Emoji' -
option_labelCharhelp='Label of the poll option'required=Truestring='Label' -
poll_idMany2one → mail.pollindex=Trueondelete='cascade'required=True args: 'mail.poll' -
selected_by_selfBooleancompute='_compute_selected_by_self' -
vote_idsOne2many → mail.poll.voteargs: 'mail.poll.vote', 'option_id' -
vote_percentageIntegercompute='_compute_vote_percentage'
-
write(self, vals)
-
guest_idMany2one → mail.guestondelete='cascade' args: 'mail.guest' -
is_self_voteBooleancompute='_compute_is_self_vote'search='_search_is_self_vote' -
option_idMany2one → mail.poll.optionindex=Trueondelete='cascade'required=True args: 'mail.poll.option' -
user_idMany2one → res.usersondelete='cascade' args: 'res.users'
-
create(self, vals_list)@api.model_create_multi
-
guest_idMany2one → mail.guestondelete='cascade' args: 'mail.guest', 'Guest' -
last_pollDatetimedefault=<expr> args: 'Last Poll' -
last_presenceDatetimedefault=<expr> args: 'Last Presence' -
statusSelectiondefault='offline' args: [('online', 'Online'), ('away', 'Away'), ('offline', 'Offline')], 'IM Status' -
user_idMany2one → res.usersondelete='cascade' args: 'res.users', 'Users'
-
create(self, vals_list)@api.model_create_multi -
unlink(self) -
write(self, vals)
-
mail_push_device_idMany2one → mail.push.deviceondelete='cascade'required=Truestring='devices' args: 'mail.push.device' -
payloadText
No public methods.
-
endpointCharrequired=Truestring='Browser endpoint' -
expiration_timeDatetimestring='Expiration Token Date' -
keysCharhelp="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=Truestring='Browser keys' -
partner_idMany2one → res.partnerdefault=<expr>index=Truerequired=Truestring='Partner' args: 'res.partner'
-
get_web_push_vapid_public_key(self)@api.model -
register_devices(self, **kw)@api.model -
unregister_devices(self, **kw)@api.model
-
langCharhelp="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_modelCharcompute='_compute_render_model'store=False args: 'Rendering Model'
-
create(self, vals_list)@api.model_create_multi -
write(self, vals)
-
attachment_idsMany2many → ir.attachmentbypass_search_access=Truestring='Attachments' args: 'ir.attachment', 'scheduled_message_attachment_rel', 'scheduled_message_id', 'attachment_id' -
author_idMany2one → res.partnerrequired=True args: 'res.partner', 'Author' -
bodyHtmlsanitize_style=True args: 'Contents' -
composition_comment_optionSelectionstring='Comment Options' args: [('reply_all', 'Reply-All'), ('forward', 'Forward')] -
is_noteBooleandefault=Falsehelp='If the message will be posted as a Note.' args: 'Is a note' -
modelCharrequired=True args: 'Related Document Model' -
notification_parametersTextargs: 'Notification parameters' -
partner_cc_idsMany2many → res.partnercontext={'active_test': False}relation='mail_scheduled_message_res_partner_cc_rel'string='Recipients (Cc)' args: 'res.partner' -
partner_idsMany2many → res.partnerstring='Recipients (To)' args: 'res.partner' -
res_accessBooleancompute='_compute_res_access'compute_sudo=Truedepends_context=('uid')groups=fields.NO_ACCESSsearch='_search_res_access' -
res_idMany2oneReferencemodel_field='model'required=True args: 'Related Document Id' -
scheduled_dateDatetimerequired=True args: 'Scheduled Date' -
send_contextJsonargs: 'Sending Context' -
subjectCharargs: 'Subject'
-
create(self, vals_list)@api.model_create_multi -
open_edit_form(self) -
post_message(self) -
write(self, vals)
-
activeBooleandefault=True -
attachment_idsMany2many → ir.attachmentbypass_search_access=Truestring='Attachments' args: 'ir.attachment', 'email_template_attachment_rel', 'email_template_id', 'attachment_id' -
auto_deleteBooleandefault=Truehelp="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_htmlHtmlprefetch=Truerender_engine='qweb'render_options={'post_process': True}sanitize='email_outgoing'translate=True args: 'Body' -
can_writeBooleancompute='_compute_can_write'help='The current user can edit the template.' -
descriptionTexthelp="This field is used for internal description of the template's usage."translate=True args: 'Template Description' -
email_ccCharhelp='Carbon copy recipients (placeholders may be used here)' args: 'Cc' -
email_fromCharhelp="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_force_footerBooleandefault=Falsehelp='If checked, the footer will be always shown in the email body when this template is used withnotification layout.' args: 'Force Footer' -
email_layout_force_headerBooleandefault=Falsehelp='If checked, the header will be always shown in the email body when this template is used withnotification layout.' args: 'Force Header' -
email_layout_xmlidCharcopy=False args: 'Email Notification Layout' -
email_toCharhelp='Comma-separated recipient addresses (placeholders may be used here)' args: 'To (Emails)' -
has_dynamic_reportsBooleancompute='_compute_has_dynamic_reports' -
has_mail_serverBooleancompute='_compute_has_mail_server' -
is_template_editorBooleancompute='_compute_is_template_editor' -
mail_server_idMany2one → ir.mail_serverhelp='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' -
modelCharindex=Truereadonly=Truerelated='model_id.model'store=True args: 'Related Document Model' -
model_idMany2one → ir.modeldomain=_get_non_abstract_models_domainondelete='cascade' args: 'ir.model', 'Applies to' -
nameChartranslate=True args: 'Name' -
partner_ccCharhelp='Comma-separated ids of recipient Cc partners (placeholders may be used here)' args: 'Cc (Partners)' -
partner_toCharhelp='Comma-separated ids of recipient To partners (placeholders may be used here)' args: 'To (Partners)' -
ref_ir_act_windowMany2one → ir.actions.act_windowcopy=Falsehelp='Sidebar action to make this template available on records of the related document model'readonly=True args: 'ir.actions.act_window', 'Sidebar action' -
reply_toCharargs: 'Reply To Address' -
report_template_idsMany2many → ir.actions.reportcolumn1='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_dateCharhelp='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' -
subjectCharhelp='Subject (placeholders may be used here)'prefetch=Truetranslate=True args: 'Subject' -
template_categorySelectioncompute='_compute_template_category'search='_search_template_category' args: [('base_template', 'Base Template'), ('hidden_template', 'Hidden Template'), ('custom_template', 'Custom Template')] -
use_default_toBooleandefault=Truehelp='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_idMany2one → res.usersdomain="[('share', '=', False)]"string='Owner' args: 'res.users'
-
action_open_mail_preview(self) -
copy(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 (may be ``False`` if no record) :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)
-
attachment_idsMany2many → ir.attachmentcompute='_compute_mail_template_fields'string='Attachments' args: 'ir.attachment' -
body_htmlHtmlcompute='_compute_mail_template_fields'sanitize=False args: 'Body' -
email_ccCharcompute='_compute_mail_template_fields'help='Carbon copy recipients' args: 'Cc' -
email_fromCharcompute='_compute_mail_template_fields'help='Sender address' args: 'From' -
email_toCharcompute='_compute_mail_template_fields'help='Comma-separated recipient addresses' args: 'To' -
error_msgCharcompute='_compute_mail_template_fields' args: 'Error Message' -
has_attachmentsBooleancompute='_compute_has_attachments' -
has_several_languages_installedBooleancompute='_compute_has_several_languages_installed' -
langSelectiondefault=<expr>string='Template Preview Language' args: _selection_languages -
mail_template_idMany2one → mail.templaterequired=Truestring='Related Mail Template' args: 'mail.template' -
model_idMany2one → ir.modelrelated='mail_template_id.model_id'string='Targeted model' args: 'ir.model' -
no_recordBooleancompute='_compute_no_record' args: 'No Record' -
partner_cc_idsMany2many → res.partnercompute='_compute_mail_template_fields'string='Recipients Cc' args: 'res.partner' -
partner_idsMany2many → res.partnercompute='_compute_mail_template_fields'string='Recipients To' args: 'res.partner' -
recipient_cc_namesCharcompute='_compute_mail_template_fields'help='Names of the Cc recipients' args: 'Recipient Cc Names' -
recipient_namesCharcompute='_compute_mail_template_fields'help='Names of the recipients' args: 'Recipient Names' -
reply_toCharcompute='_compute_mail_template_fields'help='Preferred response address' args: 'Reply-To' -
resource_refReferencecompute='_compute_resource_ref'compute_sudo=Falsereadonly=Falseselection='_selection_target_model'store=Truestring='Record' -
scheduled_dateCharcompute='_compute_mail_template_fields'help='The queue manager will send the email after the date' args: 'Scheduled Date' -
subjectCharcompute='_compute_mail_template_fields' args: 'Subject'
No public methods.
-
template_idsMany2many → mail.templateargs: 'mail.template'
-
reset_template(self)
-
has_messageBooleancompute='_compute_has_message'search='_search_has_message'store=False -
message_attachment_countIntegercompute='_compute_message_attachment_count'groups='base.group_user' args: 'Attachment Count' -
message_follower_idsOne2many → mail.followersgroups='base.group_user'string='Followers' args: 'mail.followers', 'res_id' -
message_has_errorBooleancompute='_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_counterIntegercompute='_compute_message_has_error'help='Number of messages with delivery error' args: 'Number of errors' -
message_idsOne2many → mail.messagebypass_search_access=Truedomain=<expr>string='Messages' args: 'mail.message', 'res_id' -
message_is_followerBooleancompute='_compute_message_is_follower'search='_search_message_is_follower' args: 'Is Follower' -
message_needactionBooleancompute='_compute_message_needaction'help='If checked, new messages require your attention.'search='_search_message_needaction' args: 'Action Needed' -
message_needaction_counterIntegercompute='_compute_message_needaction'help='Number of messages requiring action' args: 'Number of Actions' -
message_partner_idsMany2many → res.partnercomodel_name='res.partner'compute='_compute_message_partner_ids'inverse='_inverse_message_partner_ids'search='_search_message_partner_ids'string='Followers (Partners)'
-
create(self, vals_list)@api.model_create_multiChatter override : - subscribe uid - subscribe followers of parent - log a creation message -
get_empty_list_help(self, help_message)@api.modelOverride 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: <expr>, *, render_values: <expr>=None, message_type: str='notification', auto_commit: bool=False, **kwargs) -> MailMailSend 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 str | IrUiView 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 | None 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.modelCalled 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.modelParses 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 (unless in cc), 'cc': cc, 'recipients': delivered-to (unless in recipients_cc) + to + resent-to, 'recipients_cc': cc + 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, partner_cc_ids=None, outgoing_email_to=False, incoming_email_to=False, incoming_email_cc=False, attachments=None, attachment_ids=None, body_is_html=False, tracking_values=None, **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 list(int) partner_cc_ids: partner_ids to notify in "Cc" in addition to partner_ids and 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, bytes), tuple(str, bytes, 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 :param tracking_values: optional list of tracking values 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: <expr>, *, render_values: <expr>=None, message_type: str='notification', subtype_xmlid: str=False, subtype_id: int=False, **kwargs) -> MailMessagePost 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 str | IrUiView 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 | None 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.modelProcess 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.modelAttempt 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. -
message_update_siblings_subscription(self, partner_ids=None, subtype_ids=None) -
notify_cancel_by_type(self, notification_type)@api.modelSubclasses must call this method and then * either call the standard implementation _notify_cancel_by_type_generic * or implements their own logic -
set_message_pin(self, message_id, pinned)(Un)pin a message on the thread. The message must belong to the thread on which it is called. :param message_id: id of the message to be pinned. :param pinned: whether the message should be pinned or unpinned. -
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)
-
email_normalizedCharcompute='_compute_email_normalized'compute_sudo=Truehelp='This field is used to search on email address as the primary email field can contain more than strictly an email address.'store=Truestring='Normalized Email' -
is_blacklistedBooleancompute='_compute_is_blacklisted'compute_sudo=Truegroups='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=Falsestring='Blacklist' -
message_bounceIntegerdefault=0help='Counter of the number of bounced emails for this contact' args: 'Bounce'
-
mail_action_blacklist_remove(self)
-
message_main_attachment_idMany2one → ir.attachmentcomodel_name='ir.attachment'copy=Falseindex='btree_not_null'string='Main Attachment'
No public methods.
No new fields.
Public methods (0)No public methods.
No new fields.
Public methods (2)-
fields_get(self, allfields: <expr>=None, attributes: <expr>=None) -> <expr>@api.model -
write(self, vals)
-
duration_trackingJsoncompute='_compute_duration_tracking'help='JSON that maps ids from a many2one field to seconds spent'store=Truestring='Status time' -
is_rottingBooleancompute='_compute_rotting'search='_search_is_rotting' args: 'Rotting' -
rotting_daysIntegercompute='_compute_rotting'help='Day count since this resource was last updated' args: 'Days Rotting'
No public methods.
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
-
alias_domain_idMany2one → mail.alias.domaindefault=<expr>index='btree_not_null'string='Email Domain' args: 'mail.alias.domain' -
bounce_emailCharcompute='_compute_bounce'string='Bounce Email' -
bounce_formattedCharcompute='_compute_bounce'string='Bounce' -
catchall_emailCharcompute='_compute_catchall'string='Catchall Email' -
catchall_formattedCharcompute='_compute_catchall'string='Catchall' -
default_from_emailCharreadonly=Truerelated='alias_domain_id.default_from_email'string='Default From' -
email_formattedCharcompute='_compute_email_formatted'compute_sudo=Truestring='Formatted Email' -
email_primary_colorChardefault='#FFFFFF'readonly=False args: 'Email Button Text' -
email_secondary_colorChardefault='#875A7B'readonly=False args: 'Email Button Color'
No public methods.
-
alias_domain_idMany2one → mail.alias.domainhelp='If you have setup a catch-all email domain redirected to the Odoo server, enter the domain name here.'readonly=Falserelated='company_id.alias_domain_id' args: 'mail.alias.domain', 'Alias Domain' -
email_primary_colorCharreadonly=Falserelated='company_id.email_primary_color' -
email_secondary_colorCharreadonly=Falserelated='company_id.email_secondary_color' -
external_email_server_defaultBooleanconfig_parameter='base_setup.default_external_email_server' args: 'Use Custom Email Servers' -
fail_counterIntegercompute='_compute_fail_counter' args: 'Fail Mail' -
google_translate_api_keyCharconfig_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_gmailBooleanargs: 'Support Gmail Authentication' -
module_microsoft_outlookBooleanargs: 'Support Outlook Authentication' -
restrict_template_renderingBooleanconfig_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_client_sourceTexthelp='SFU JS client bundle loaded by every SFU participant' args: 'SFU Client Bundle' -
sfu_server_keyCharconfig_parameter='mail.sfu_server_key'help='Base64 encoded key' args: 'SFU Server key' -
sfu_server_urlCharconfig_parameter='mail.sfu_server_url' args: 'SFU Server URL' -
tenor_api_keyCharconfig_parameter='discuss.klipy_api_key'help='Add a Klipy GIF API key to enable GIFs support. https://docs.klipy.com/getting-started' args: 'Klipy API key' -
twilio_account_sidCharconfig_parameter='mail.twilio_account_sid' args: 'Account SID' -
twilio_account_tokenCharconfig_parameter='mail.twilio_account_token' args: 'Account Auth Token' -
use_call_serverBooleanconfig_parameter='mail.use_call_server'help='If you want to use your own SFU or ICE servers for video calls.' args: 'Use Call Server' -
use_custom_sfu_clientBooleanargs: 'Use Custom SFU Bundle' -
use_google_translate_apiBooleanconfig_parameter='mail.use_google_translate_api'help='If you want to use Google Translate API to enable message translation.' args: 'Use Google Translate API' -
use_sfu_serverBooleanconfig_parameter='mail.use_sfu_server'help='If you want to setup SFU server for large group calls.' args: 'Use SFU server' -
use_tenor_apiBooleanconfig_parameter='discuss.use_klipy_api'help='If you want to use Klipy API to share GIFs in conversations.' args: 'Use Klipy API' -
use_twilio_rtc_serversBooleanconfig_parameter='mail.use_twilio_rtc_servers'help='If you want to use twilio as TURN/STUN server provider' args: 'Use Twilio ICE servers'
-
action_open_sfu_client_source(self) -
action_save_sfu_client_asset(self) -
get_values(self)@api.model -
open_email_layout(self) -
open_mail_templates(self) -
set_values(self)
No new fields.
Public methods (0)No public methods.
No new fields.
Public methods (1)-
write(self, vals)
-
contact_address_inlineChartracking=True -
emailChartracking=1 -
nameChartracking=1 -
parent_idMany2onetracking=3 -
phoneChartracking=2 -
user_idMany2onetracking=4 -
vatChartracking=5
-
create(self, vals_list)@api.model_create_multi -
find_or_create(self, email, assert_valid_email=False)@api.modelOverride to use the email_normalized field. -
get_mention_suggestions(self, search, limit=8, internal_users_only=False)@api.readonly@api.modelReturn '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.
-
channel_idsMany2many → discuss.channelcopy=Falsestring='Channels' args: 'discuss.channel', 'discuss_channel_member', 'partner_id', 'channel_id' -
channel_member_idsOne2many → discuss.channel.memberargs: 'discuss.channel.member', 'partner_id' -
is_in_callBooleancompute='_compute_is_in_call'groups='base.group_system' -
rtc_session_idsOne2many → discuss.channel.rtc.sessionargs: 'discuss.channel.rtc.session', 'partner_id'
-
get_mention_suggestions_from_channel(self, channel_id, search, limit=8)@api.readonly@api.modelReturn '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. -
search_for_channel_invite(self, search_term, channel_id=None, limit=30, with_portal_users=False)@api.readonly@api.modelReturns 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. :param with_portal_users: whether portal users may be included in the results. Should only be set when the channel configuration actually allows portal users to be invited (e.g. a "group" channel), as including them is significantly more expensive.
-
activeBooleandefault=True -
nameCharrequired=True -
user_idsMany2many → res.usersrelation='res_role_res_users_rel'string='Users' args: 'res.users' -
user_ids_countIntegercompute='_compute_user_ids_count'
No public methods.
-
can_edit_roleBooleancompute='_compute_can_edit_role' -
emailChartracking=2 -
has_external_mail_serverBooleancompute='_compute_has_external_mail_server'compute_sudo=True -
im_statusSelectioncompute='_compute_im_status'compute_sudo=True args: [('online', 'Online'), ('away', 'Away'), ('busy', 'Do Not Disturb'), ('offline', 'Offline')], 'IM Status' -
is_out_of_officeBooleancompute='_compute_is_out_of_office' args: 'Out of Office' -
loginChartracking=4 -
manual_im_statusSelectionstring='IM status manually set by the user' args: [('away', 'Away'), ('busy', 'Do Not Disturb'), ('offline', 'Offline')] -
nameChartracking=1 -
notification_typeSelectioncompute='_compute_notification_type'default='email'help='How notifications for document messages and system updates are delivered:\n- By email: Notifications are sent to your email address.\n- In Odoo: Notifications appear in your Odoo inbox.'inverse='_inverse_notification_type'required=Truestore=Trueuser_writeable=True args: [('email', 'By Emails'), ('inbox', 'In Odoo')], 'Notification' -
offline_sinceDatetimecompute='_compute_im_status'compute_sudo=True args: 'Offline since' -
out_of_office_fromDatetimeuser_writeable=True -
out_of_office_messageHtmluser_writeable=True args: 'Vacation Responder' -
out_of_office_toDatetimeuser_writeable=True -
outgoing_mail_server_idMany2one → ir.mail_servercompute='_compute_outgoing_mail_server_id' args: 'ir.mail_server', 'Outgoing Mail Server' -
outgoing_mail_server_typeSelectioncompute='_compute_outgoing_mail_server_id'default='default'required=True args: [('default', 'Default')], 'Outgoing Mail Server Type' -
phoneChartracking=3 -
presence_idsOne2many → mail.presencegroups='base.group_system' args: 'mail.presence', 'user_id' -
role_idsMany2many → res.rolehelp='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'
-
action_archive(self) -
action_setup_outgoing_mail_server(self, server_type)@api.modelConfigure the outgoing mail servers. -
action_test_outgoing_mail_server(self)@api.model -
create(self, vals_list)@api.model_create_multi -
write(self, vals)
-
is_in_callBooleanrelated='partner_id.is_in_call' args: 'Is in call'
-
create(self, vals_list)@api.model_create_multi -
unlink(self) -
write(self, vals)
-
channel_notificationsSelectionhelp='This setting will only be applied to channels. Mentions only if not specified.' args: [('all', 'All Messages'), ('no_notif', 'Nothing')], 'Channel Notifications' -
volume_settings_idsOne2many → res.users.settings.volumesstring='Volumes of other partners' args: 'res.users.settings.volumes', 'user_setting_id'
-
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:
-
guest_idMany2one → res.partnerindex=Trueondelete='cascade' args: 'res.partner' -
partner_idMany2one → res.partnerindex=Trueondelete='cascade' args: 'res.partner' -
user_setting_idMany2one → res.users.settingsindex=Trueondelete='cascade'required=True args: 'res.users.settings' -
volumeFloatdefault=0.5help='Ranges between 0.0 and 1.0, scale depends on the browser implementation'
No public methods.
-
template_fsCharcopy=Falsehelp='File from where the template originates. Used to reset broken template.'string='Template Filename'
-
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…
Loading…