From 418761e34412677192b57a497f1d78908b7686c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 13 Sep 2022 12:18:53 +0000 Subject: [PATCH] [LINT] mail, various: use explicit subtype in message_post_{with_...} RATIONALE Purpose of this commit is to be explicit in subtype chosen when invoking the message composer / calling message_post. As default value may not always be clear, better be explicit in case the composer default value changes. SPECIFICATIONS Add explicit references to subtype when it is not obvious what will be the final subtype, notably when using helpers (post_with_view or template which uses the composer that is not crystal clear in its subtype management). In this commit we also add support of XMLID-based subtype when invoking the composer. A ``default_subtype_xmlid`` context key is transformed into a ``default_subtype_id``, to be used notably in JS where we cannot easily use a ``ref``-like statement. Post API now also supports 'subytpe_xmlid' argument allowing to give the xml id and ease calling the methods. Use ``_xmlid_to_res_id`` to get directly the ID of subtypes in order to avoid useless queries from ``ref`` that does an exists. Also remove useless values given to post API, notably author_id that is by default the current users' partner. Task-2710804 (Mail: Clean MailThread Posting API) Part-of: odoo/odoo#99482 --- addons/account/wizard/account_invoice_send.py | 4 ++- addons/crm/models/crm_lead.py | 2 +- addons/crm_iap_enrich/models/crm_lead.py | 13 ++++++--- .../models/crm_iap_lead_mining_request.py | 6 +++- addons/event_booth/models/event_booth.py | 2 +- .../event_sale/models/event_registration.py | 3 +- addons/hr_expense/models/hr_expense.py | 28 ++++++++++++------- addons/hr_recruitment/models/hr_employee.py | 4 +-- .../wizard/applicant_refuse_reason.py | 11 ++++---- .../models/hr_contract.py | 4 +-- addons/mail/models/mail_activity.py | 2 +- addons/mail/models/mail_activity_mixin.py | 3 +- addons/mail/models/mail_blacklist.py | 4 +-- addons/mail/models/mail_thread.py | 12 ++++++-- .../mail/static/src/models/composer_view.js | 1 + .../mail/static/src/models/mail_template.js | 1 + addons/mail/views/res_partner_views.xml | 1 + addons/mail/wizard/mail_compose_message.py | 7 +++++ addons/mail_plugin/controllers/mail_plugin.py | 4 +-- addons/mass_mailing/models/mail_thread.py | 5 ++-- addons/mrp/models/mrp_unbuild.py | 3 +- addons/mrp/models/stock_rule.py | 10 +++++-- .../models/res_company.py | 2 +- .../models/res_partner.py | 2 +- .../models/phone_blacklist.py | 4 +-- addons/portal/wizard/portal_share.py | 17 ++++------- .../models/account_move.py | 4 ++- addons/project/wizard/project_share_wizard.py | 5 ++-- addons/purchase/models/purchase.py | 16 +++++++---- .../purchase_requisition/models/purchase.py | 6 ++-- addons/purchase_stock/models/purchase.py | 3 +- addons/rating/models/rating_mixin.py | 5 ++-- addons/sale/models/payment_transaction.py | 10 ++++--- addons/sale/models/sale_order.py | 5 ++-- addons/sale/tests/test_controllers.py | 4 ++- addons/sale/tests/test_sale_order.py | 10 +++++-- addons/sale/tests/test_sale_to_invoice.py | 5 +++- .../sale/wizard/sale_make_invoice_advance.py | 3 +- addons/sale_stock/models/stock.py | 3 +- addons/stock/models/stock_move_line.py | 6 +++- addons/stock/models/stock_picking.py | 7 ++++- addons/stock/wizard/stock_picking_return.py | 6 ++-- addons/test_mail/models/test_mail_models.py | 16 +++++++++-- .../test_mail/static/tests/activity_tests.js | 1 + addons/test_mail/tests/test_mail_composer.py | 10 +++++++ addons/test_mail/tests/test_message_post.py | 6 ++-- addons/test_mail/tests/test_performance.py | 8 +++++- addons/website_blog/models/website_blog.py | 3 +- .../models/crm_reveal_rule.py | 2 +- .../website_event_track/models/event_track.py | 10 +++---- addons/website_forum/models/forum.py | 9 ++++-- 51 files changed, 214 insertions(+), 104 deletions(-) diff --git a/addons/account/wizard/account_invoice_send.py b/addons/account/wizard/account_invoice_send.py index 4c086fe6c8b..2b26e609e3a 100644 --- a/addons/account/wizard/account_invoice_send.py +++ b/addons/account/wizard/account_invoice_send.py @@ -41,6 +41,7 @@ class AccountInvoiceSend(models.TransientModel): composer = self.env['mail.compose.message'].create({ 'composition_mode': 'comment' if len(res_ids) == 1 else 'mass_mail', + 'subtype_id': self.env['ir.model.data']._xmlid_to_res_id('mail.mt_comment'), }) res.update({ 'invoice_ids': res_ids, @@ -86,7 +87,8 @@ class AccountInvoiceSend(models.TransientModel): if not self.composer_id: self.composer_id = self.env['mail.compose.message'].create({ 'composition_mode': 'comment' if len(res_ids) == 1 else 'mass_mail', - 'template_id': self.template_id.id + 'subtype_id': self.env['ir.model.data']._xmlid_to_res_id('mail.mt_comment'), + 'template_id': self.template_id.id, }) else: self.composer_id.composition_mode = 'comment' if len(res_ids) == 1 else 'mass_mail' diff --git a/addons/crm/models/crm_lead.py b/addons/crm/models/crm_lead.py index 89189d5c4cc..0442fe57ed5 100644 --- a/addons/crm/models/crm_lead.py +++ b/addons/crm/models/crm_lead.py @@ -1568,7 +1568,7 @@ class Lead(models.Model): "opportunities": opportunities_tail, "is_html_empty": is_html_empty, }, - subtype_id=self.env.ref('mail.mt_note').id, + subtype_xmlid='mail.mt_note', ) def _format_properties(self): diff --git a/addons/crm_iap_enrich/models/crm_lead.py b/addons/crm_iap_enrich/models/crm_lead.py index 9685eab24a5..6732e2ee57e 100644 --- a/addons/crm_iap_enrich/models/crm_lead.py +++ b/addons/crm_iap_enrich/models/crm_lead.py @@ -70,7 +70,8 @@ class Lead(models.Model): if not normalized_email: lead.message_post_with_view( 'crm_iap_enrich.mail_message_lead_enrich_no_email', - subtype_id=self.env.ref('mail.mt_note').id) + subtype_xmlid='mail.mt_note', + ) continue email_domain = normalized_email.split('@')[1] @@ -79,7 +80,8 @@ class Lead(models.Model): lead.write({'iap_enrich_done': True}) lead.message_post_with_view( 'crm_iap_enrich.mail_message_lead_enrich_notfound', - subtype_id=self.env.ref('mail.mt_note').id) + subtype_xmlid='mail.mt_note', + ) else: lead_emails[lead.id] = email_domain @@ -126,7 +128,10 @@ class Lead(models.Model): iap_data = iap_response.get(str(lead.id)) if not iap_data: lead.write({'iap_enrich_done': True}) - lead.message_post_with_view('crm_iap_enrich.mail_message_lead_enrich_notfound', subtype_id=self.env.ref('mail.mt_note').id) + lead.message_post_with_view( + 'crm_iap_enrich.mail_message_lead_enrich_notfound', + subtype_xmlid='mail.mt_note', + ) continue values = {'iap_enrich_done': True} @@ -159,7 +164,7 @@ class Lead(models.Model): lead.message_post_with_view( 'iap_mail.enrich_company', values=template_values, - subtype_id=self.env.ref('mail.mt_note').id + subtype_xmlid='mail.mt_note', ) def _merge_get_fields_specific(self): diff --git a/addons/crm_iap_mine/models/crm_iap_lead_mining_request.py b/addons/crm_iap_mine/models/crm_iap_lead_mining_request.py index 5796a61cff9..cb9ef3c4e66 100644 --- a/addons/crm_iap_mine/models/crm_iap_lead_mining_request.py +++ b/addons/crm_iap_mine/models/crm_iap_lead_mining_request.py @@ -278,7 +278,11 @@ class CRMLeadMiningRequest(models.Model): leads = self.env['crm.lead'].create(lead_vals_list) for lead in leads: if messages_to_post.get(lead.reveal_id): - lead.message_post_with_view('iap_mail.enrich_company', values=messages_to_post[lead.reveal_id], subtype_id=self.env.ref('mail.mt_note').id) + lead.message_post_with_view( + 'iap_mail.enrich_company', + values=messages_to_post[lead.reveal_id], + subtype_xmlid='mail.mt_note', + ) # Methods responsible for format response data into valid odoo lead data @api.model diff --git a/addons/event_booth/models/event_booth.py b/addons/event_booth/models/event_booth.py index 4ca2433ae0c..474ea92c545 100644 --- a/addons/event_booth/models/event_booth.py +++ b/addons/event_booth/models/event_booth.py @@ -105,7 +105,7 @@ class EventBooth(models.Model): values={ 'booth': booth, }, - subtype_id=self.env.ref('event_booth.mt_event_booth_booked').id, + subtype_xmlid='event_booth.mt_event_booth_booked', ) def action_confirm(self, additional_values=None): diff --git a/addons/event_sale/models/event_registration.py b/addons/event_sale/models/event_registration.py index 46f169a0ffc..95c0f47ec46 100644 --- a/addons/event_sale/models/event_registration.py +++ b/addons/event_sale/models/event_registration.py @@ -80,7 +80,8 @@ class EventRegistration(models.Model): registration.message_post_with_view( 'mail.message_origin_link', values={'self': registration, 'origin': registration.sale_order_id}, - subtype_id=self.env.ref('mail.mt_note').id) + subtype_xmlid='mail.mt_note', + ) return registrations def write(self, vals): diff --git a/addons/hr_expense/models/hr_expense.py b/addons/hr_expense/models/hr_expense.py index ba758e8b7f7..6fd2566fdd8 100644 --- a/addons/hr_expense/models/hr_expense.py +++ b/addons/hr_expense/models/hr_expense.py @@ -636,8 +636,11 @@ class HrExpense(models.Model): def refuse_expense(self, reason): self.write({'is_refused': True}) self.sheet_id.write({'state': 'cancel'}) - self.sheet_id.message_post_with_view('hr_expense.hr_expense_template_refuse_reason', - values={'reason': reason, 'is_sheet': False, 'name': self.name}) + self.sheet_id.message_post_with_view( + 'hr_expense.hr_expense_template_refuse_reason', + values={'reason': reason, 'is_sheet': False, 'name': self.name}, + subtype_xmlid='mail.mt_comment', + ) @api.model def get_expense_dashboard(self): @@ -798,21 +801,21 @@ class HrExpense(models.Model): # TDE TODO: seems louche, check to use notify if expense.employee_id.user_id.partner_id: expense.message_post( + body=body, + email_layout_xmlid='mail.mail_notification_light', partner_ids=expense.employee_id.user_id.partner_id.ids, subject='Re: %s' % msg_dict.get('subject', ''), - body=body, - subtype_id=self.env.ref('mail.mt_note').id, - email_layout_xmlid='mail.mail_notification_light', + subtype_xmlid='mail.mt_note', ) else: self.env['mail.mail'].sudo().create({ - 'email_from': self.env.user.email_formatted, 'author_id': self.env.user.partner_id.id, - 'body_html': body, - 'subject': 'Re: %s' % msg_dict.get('subject', ''), - 'email_to': msg_dict.get('email_from', False), 'auto_delete': True, + 'body_html': body, + 'email_from': self.env.user.email_formatted, + 'email_to': msg_dict.get('email_from', False), 'references': msg_dict.get('message_id'), + 'subject': 'Re: %s' % msg_dict.get('subject', ''), }).send() @@ -1213,8 +1216,13 @@ class HrExpenseSheet(models.Model): raise UserError(_("You can only refuse your department expenses")) self.write({'state': 'cancel'}) + subtype_id = self.env['ir.model.data']._xmlid_to_res_id('mail.mt_comment') for sheet in self: - sheet.message_post_with_view('hr_expense.hr_expense_template_refuse_reason', values={'reason': reason, 'is_sheet': True, 'name': sheet.name}) + sheet.message_post_with_view( + 'hr_expense.hr_expense_template_refuse_reason', + subtype_id=subtype_id, + values={'reason': reason, 'is_sheet': True, 'name': sheet.name}, + ) self.activity_update() def reset_expense_sheets(self): diff --git a/addons/hr_recruitment/models/hr_employee.py b/addons/hr_recruitment/models/hr_employee.py index cb7d7fe0195..4013d5ceebc 100644 --- a/addons/hr_recruitment/models/hr_employee.py +++ b/addons/hr_recruitment/models/hr_employee.py @@ -1,7 +1,6 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from odoo import api, fields, models -from odoo.tools.translate import _ from datetime import timedelta @@ -31,5 +30,6 @@ class HrEmployee(models.Model): employee.applicant_id.message_post_with_view( 'hr_recruitment.applicant_hired_template', values={'applicant': employee.applicant_id}, - subtype_id=self.env.ref("hr_recruitment.mt_applicant_hired").id) + subtype_xmlid='hr_recruitment.mt_applicant_hired', + ) return employees diff --git a/addons/hr_recruitment/wizard/applicant_refuse_reason.py b/addons/hr_recruitment/wizard/applicant_refuse_reason.py index 4f27bea09ad..d44413b3d94 100644 --- a/addons/hr_recruitment/wizard/applicant_refuse_reason.py +++ b/addons/hr_recruitment/wizard/applicant_refuse_reason.py @@ -45,8 +45,9 @@ class ApplicantGetRefuseReason(models.TransientModel): self.applicant_ids.write({'refuse_reason_id': self.refuse_reason_id.id, 'active': False}) if self.send_mail: applicants = self.applicant_ids.filtered(lambda x: x.email_from or x.partner_id.email) - applicants.with_context(active_test=True).message_post_with_template(self.template_id.id, **{ - 'auto_delete_message': True, - 'subtype_id': self.env['ir.model.data']._xmlid_to_res_id('mail.mt_note'), - 'email_layout_xmlid': 'mail.mail_notification_light' - }) + applicants.with_context(active_test=True).message_post_with_template( + self.template_id.id, + auto_delete_message=True, + email_layout_xmlid='mail.mail_notification_light', + subtype_xmlid='mail.mt_note', + ) diff --git a/addons/hr_work_entry_holidays/models/hr_contract.py b/addons/hr_work_entry_holidays/models/hr_contract.py index 22a01619ecc..2b608ce38df 100644 --- a/addons/hr_work_entry_holidays/models/hr_contract.py +++ b/addons/hr_work_entry_holidays/models/hr_contract.py @@ -134,9 +134,9 @@ class HrContract(models.Model): ).create(all_new_leave_vals) new_leaves.filtered(lambda l: l.state in 'validate')._validate_leave_request() for index, new_leave in enumerate(new_leaves): - subtype_note = self.env.ref('mail.mt_note') new_leave.message_post_with_view( 'mail.message_origin_link', values={'self': new_leave, 'origin': all_new_leave_origin[index]}, - subtype_id=subtype_note.id) + subtype_xmlid='mail.mt_note', + ) return super(HrContract, self - specific_contracts).write(vals) diff --git a/addons/mail/models/mail_activity.py b/addons/mail/models/mail_activity.py index fd4d3a925e8..593c170c10e 100644 --- a/addons/mail/models/mail_activity.py +++ b/addons/mail/models/mail_activity.py @@ -581,7 +581,7 @@ class MailActivity(models.Model): 'feedback': feedback, 'display_assignee': activity.user_id != self.env.user }, - subtype_id=self.env['ir.model.data']._xmlid_to_res_id('mail.mt_activities'), + subtype_xmlid='mail.mt_activities', mail_activity_type_id=activity.activity_type_id.id, attachment_ids=[Command.link(attachment_id) for attachment_id in attachment_ids] if attachment_ids else [], ) diff --git a/addons/mail/models/mail_activity_mixin.py b/addons/mail/models/mail_activity_mixin.py index 3c0542b110a..3d5fcb94e46 100644 --- a/addons/mail/models/mail_activity_mixin.py +++ b/addons/mail/models/mail_activity_mixin.py @@ -345,7 +345,8 @@ class MailActivityMixin(models.AbstractModel): for record in self: record.message_post_with_template( template_id, - composition_mode='comment' + composition_mode='comment', + subtype_xmlid='mail.mt_comment', ) return True diff --git a/addons/mail/models/mail_blacklist.py b/addons/mail/models/mail_blacklist.py index 7adf2476721..a4fcd1e9cf4 100644 --- a/addons/mail/models/mail_blacklist.py +++ b/addons/mail/models/mail_blacklist.py @@ -81,7 +81,7 @@ class MailBlackList(models.Model): if message: record.with_context(mail_create_nosubscribe=True).message_post( body=message, - subtype_id=self.env.ref('mail.mt_note').id, + subtype_xmlid='mail.mt_note', ) return record @@ -97,7 +97,7 @@ class MailBlackList(models.Model): if message: record.with_context(mail_create_nosubscribe=True).message_post( body=message, - subtype_id=self.env.ref('mail.mt_note').id, + subtype_xmlid='mail.mt_note', ) return record diff --git a/addons/mail/models/mail_thread.py b/addons/mail/models/mail_thread.py index 763889896dd..3cbf9e7204a 100644 --- a/addons/mail/models/mail_thread.py +++ b/addons/mail/models/mail_thread.py @@ -2119,6 +2119,10 @@ class MailThread(models.AbstractModel): res_id = kwargs.get('res_id', self.ids and self.ids[0] or 0) res_ids = kwargs.get('res_id') and [kwargs['res_id']] or self.ids + # support xml based subtype id + if kwargs.get('subtype_xmlid') and not kwargs.get('subtype_id'): + kwargs['subtype_id'] = self.env['ir.model.data']._xmlid_to_res_id(kwargs.pop('subtype_xmlid')) + # Create the composer composer = self.env['mail.compose.message'].with_context( active_id=res_id, @@ -2139,7 +2143,9 @@ class MailThread(models.AbstractModel): def message_notify(self, *, partner_ids=False, parent_id=False, model=False, res_id=False, - author_id=None, email_from=None, body='', subject=False, **kwargs): + author_id=None, email_from=None, body='', subject=False, + subtype_xmlid=None, + **kwargs): """ Shortcut allowing to notify partners of messages that shouldn't be displayed on a document. It pushes notifications on inbox or by email depending on the user configuration, like other notifications. """ @@ -2181,7 +2187,9 @@ class MailThread(models.AbstractModel): } msg_values.update(msg_kwargs) # add default-like values afterwards, to avoid useless queries - if 'subtype_id' not in msg_values: + if subtype_xmlid: + msg_values['subtype_id'] = self.env['ir.model.data']._xmlid_to_res_id(subtype_xmlid) + elif 'subtype_id' not in msg_values: msg_values['subtype_id'] = self.env['ir.model.data']._xmlid_to_res_id('mail.mt_note') if 'reply_to' not in msg_values: msg_values['reply_to'] = self._notify_get_reply_to(default=email_from)[self.id if self else False] diff --git a/addons/mail/static/src/models/composer_view.js b/addons/mail/static/src/models/composer_view.js index 21dc7f63da5..6ff29361d84 100644 --- a/addons/mail/static/src/models/composer_view.js +++ b/addons/mail/static/src/models/composer_view.js @@ -551,6 +551,7 @@ Model({ default_model: this.composer.activeThread.model, default_partner_ids: this.composer.recipients.map((partner) => partner.id), default_res_id: this.composer.activeThread.id, + default_subtype_xmlid: 'mail.mt_comment', mail_post_autofollow: this.composer.activeThread.hasWriteAccess, }; diff --git a/addons/mail/static/src/models/mail_template.js b/addons/mail/static/src/models/mail_template.js index 0168b6c9603..100afeac761 100644 --- a/addons/mail/static/src/models/mail_template.js +++ b/addons/mail/static/src/models/mail_template.js @@ -19,6 +19,7 @@ Model({ default_res_id: activity.thread.id, default_model: activity.thread.model, default_use_template: true, + default_subtype_xmlid: 'mail.mt_comment', default_template_id: this.id, force_email: true, }, diff --git a/addons/mail/views/res_partner_views.xml b/addons/mail/views/res_partner_views.xml index 08e7835b610..a3fae6a1d55 100644 --- a/addons/mail/views/res_partner_views.xml +++ b/addons/mail/views/res_partner_views.xml @@ -110,6 +110,7 @@ diff --git a/addons/mail/wizard/mail_compose_message.py b/addons/mail/wizard/mail_compose_message.py index d70d51fe5be..c058b8c0e93 100644 --- a/addons/mail/wizard/mail_compose_message.py +++ b/addons/mail/wizard/mail_compose_message.py @@ -54,6 +54,13 @@ class MailComposer(models.TransientModel): # email_layout_xmlid field: to remove in 15.1+ if self._context.get('custom_layout') and 'default_email_layout_xmlid' not in self._context: self = self.with_context(default_email_layout_xmlid=self._context['custom_layout']) + # support subtype xmlid, like ``message_post``, when easier than using ``ref`` + if self.env.context.get('default_subtype_xmlid'): + self = self.with_context( + default_subtype_id=self.env['ir.model.data']._xmlid_to_res_id( + self.env.context['default_subtype_xmlid'] + ) + ) result = super(MailComposer, self).default_get(fields) diff --git a/addons/mail_plugin/controllers/mail_plugin.py b/addons/mail_plugin/controllers/mail_plugin.py index b2478ef6779..22a5506302a 100644 --- a/addons/mail_plugin/controllers/mail_plugin.py +++ b/addons/mail_plugin/controllers/mail_plugin.py @@ -120,7 +120,7 @@ class MailPluginController(http.Controller): partner.message_post_with_view( 'iap_mail.enrich_company', values=iap_data, - subtype_id=request.env.ref('mail.mt_note').id, + subtype_xmlid='mail.mt_note', ) return { @@ -360,7 +360,7 @@ class MailPluginController(http.Controller): new_company.message_post_with_view( 'iap_mail.enrich_company', values=iap_data, - subtype_id=request.env.ref('mail.mt_note').id, + subtype_xmlid='mail.mt_note', ) return new_company, {'type': 'company_created'} diff --git a/addons/mass_mailing/models/mail_thread.py b/addons/mass_mailing/models/mail_thread.py index fff1aea4641..7c98349dab6 100644 --- a/addons/mass_mailing/models/mail_thread.py +++ b/addons/mass_mailing/models/mail_thread.py @@ -31,11 +31,10 @@ class MailThread(models.AbstractModel): def message_post_with_template(self, template_id, **kwargs): # avoid having message send through `message_post*` methods being implicitly considered as # mass-mailing - no_massmail = self.with_context( + return super(MailThread, self.with_context( default_mass_mailing_name=False, default_mass_mailing_id=False, - ) - return super(MailThread, no_massmail).message_post_with_template(template_id, **kwargs) + )).message_post_with_template(template_id, **kwargs) @api.model def _routing_handle_bounce(self, email_message, message_dict): diff --git a/addons/mrp/models/mrp_unbuild.py b/addons/mrp/models/mrp_unbuild.py index 12747d5a732..d37523ef0e1 100644 --- a/addons/mrp/models/mrp_unbuild.py +++ b/addons/mrp/models/mrp_unbuild.py @@ -212,7 +212,8 @@ class MrpUnbuild(models.Model): ) self.mo_id.message_post( body=unbuild_msg, - subtype_id=self.env.ref('mail.mt_note').id) + subtype_xmlid='mail.mt_note', + ) return self.write({'state': 'done'}) def _generate_consume_moves(self): diff --git a/addons/mrp/models/stock_rule.py b/addons/mrp/models/stock_rule.py index ae8faf098ef..58e5c7d0a56 100644 --- a/addons/mrp/models/stock_rule.py +++ b/addons/mrp/models/stock_rule.py @@ -48,6 +48,7 @@ class StockRule(models.Model): productions_values_by_company[procurement.company_id.id].append(rule._prepare_mo_vals(*procurement, bom)) + note_subtype_id = self.env['ir.model.data']._xmlid_to_res_id('mail.mt_note') for company_id, productions_values in productions_values_by_company.items(): # create the MO as SUPERUSER because the current user may not have the rights to do it (mto product launched by a sale for example) productions = self.env['mrp.production'].with_user(SUPERUSER_ID).sudo().with_company(company_id).create(productions_values) @@ -61,17 +62,20 @@ class StockRule(models.Model): production.message_post( body=_('This production order has been created from Replenishment Report.'), message_type='comment', - subtype_xmlid='mail.mt_note') + subtype_id=note_subtype_id + ) elif orderpoint: production.message_post_with_view( 'mail.message_origin_link', values={'self': production, 'origin': orderpoint}, - subtype_id=self.env.ref('mail.mt_note').id) + subtype_id=note_subtype_id, + ) elif origin_production: production.message_post_with_view( 'mail.message_origin_link', values={'self': production, 'origin': origin_production}, - subtype_id=self.env.ref('mail.mt_note').id) + subtype_id=note_subtype_id, + ) return True @api.model diff --git a/addons/partner_autocomplete/models/res_company.py b/addons/partner_autocomplete/models/res_company.py index ecaec41dda5..b033898e3a7 100644 --- a/addons/partner_autocomplete/models/res_company.py +++ b/addons/partner_autocomplete/models/res_company.py @@ -84,7 +84,7 @@ class ResCompany(models.Model): self.partner_id.message_post_with_view( 'iap_mail.enrich_company', values=template_values, - subtype_id=self.env.ref('mail.mt_note').id, + subtype_xmlid='mail.mt_note', ) return True diff --git a/addons/partner_autocomplete/models/res_partner.py b/addons/partner_autocomplete/models/res_partner.py index 19a947f64f7..8de11eeaa09 100644 --- a/addons/partner_autocomplete/models/res_partner.py +++ b/addons/partner_autocomplete/models/res_partner.py @@ -169,7 +169,7 @@ class ResPartner(models.Model): partners.message_post_with_view( 'iap_mail.enrich_company', values=template_values, - subtype_id=self.env.ref('mail.mt_note').id, + subtype_xmlid='mail.mt_note', ) partners.write({'additional_info': False}) diff --git a/addons/phone_validation/models/phone_blacklist.py b/addons/phone_validation/models/phone_blacklist.py index 8ce9b5ef4d3..f940a9fb6b9 100644 --- a/addons/phone_validation/models/phone_blacklist.py +++ b/addons/phone_validation/models/phone_blacklist.py @@ -98,7 +98,7 @@ class PhoneBlackList(models.Model): for record in new_records: record.with_context(mail_create_nosubscribe=True).message_post( body=message, - subtype_id=self.env.ref('mail.mt_note').id, + subtype_xmlid='mail.mt_note', ) records += new_records return records @@ -123,7 +123,7 @@ class PhoneBlackList(models.Model): for record in new_records: record.with_context(mail_create_nosubscribe=True).message_post( body=message, - subtype_id=self.env.ref('mail.mt_note').id, + subtype_xmlid='mail.mt_note', ) records += new_records return records diff --git a/addons/portal/wizard/portal_share.py b/addons/portal/wizard/portal_share.py index 5f1dc177ceb..1bc76e32418 100644 --- a/addons/portal/wizard/portal_share.py +++ b/addons/portal/wizard/portal_share.py @@ -57,11 +57,7 @@ class PortalShare(models.TransientModel): record = res_model.browse(rec.res_id) rec.access_warning = record.access_warning - @api.model - def _get_note(self): - return self.env.ref('mail.mt_note') - - def _send_public_link(self, note, partners=None): + def _send_public_link(self, partners=None): if partners is None: partners = self.partner_ids for partner in partners: @@ -73,12 +69,12 @@ class PortalShare(models.TransientModel): values={'partner': partner, 'note': self.note, 'record': self.resource_ref, 'share_link': share_link}, subject=_("You are invited to access %s", self.resource_ref.display_name), - subtype_id=note.id, + subtype_xmlid='mail.mt_note', email_layout_xmlid='mail.mail_notification_light', partner_ids=[(6, 0, partner.ids)]) self = self.with_context(lang=saved_lang) - def _send_signup_link(self, note, partners=None): + def _send_signup_link(self, partners=None): if partners is None: partners = self.partner_ids.filtered(lambda partner: not partner.user_ids) for partner in partners: @@ -92,13 +88,12 @@ class PortalShare(models.TransientModel): values={'partner': partner, 'note': self.note, 'record': self.resource_ref, 'share_link': share_link}, subject=_("You are invited to access %s", self.resource_ref.display_name), - subtype_id=note.id, + subtype_xmlid='mail.mt_note', email_layout_xmlid='mail.mail_notification_light', partner_ids=[(6, 0, partner.ids)]) self = self.with_context(lang=saved_lang) def action_send_mail(self): - note = self._get_note() signup_enabled = self.env['ir.config_parameter'].sudo().get_param('auth_signup.invitation_scope') == 'b2c' if getattr(self.resource_ref, 'access_token', False) or not signup_enabled: @@ -106,9 +101,9 @@ class PortalShare(models.TransientModel): else: partner_ids = self.partner_ids.filtered(lambda x: x.user_ids) # if partner already user or record has access token send common link in batch to all user - self._send_public_link(note, partner_ids) + self._send_public_link(partner_ids) # when partner not user send individual mail with signup token - self._send_signup_link(note, self.partner_ids - partner_ids) + self._send_signup_link(self.partner_ids - partner_ids) # subscribe all recipients so that they receive future communication (better than # using autofollow as more precise) diff --git a/addons/product_email_template/models/account_move.py b/addons/product_email_template/models/account_move.py index 07039372614..0c240542111 100644 --- a/addons/product_email_template/models/account_move.py +++ b/addons/product_email_template/models/account_move.py @@ -15,12 +15,14 @@ class AccountMove(models.Model): # subscribe the partner to the invoice if invoice.partner_id not in invoice.message_partner_ids: invoice.message_subscribe([invoice.partner_id.id]) + comment_subtype_id = self.env['ir.model.data']._xmlid_to_res_id('mail.mt_comment') for line in invoice.invoice_line_ids: if line.product_id.email_template_id: invoice.message_post_with_template( line.product_id.email_template_id.id, composition_mode="comment", - email_layout_xmlid="mail.mail_notification_light" + email_layout_xmlid="mail.mail_notification_light", + subtype_id=comment_subtype_id, ) return True diff --git a/addons/project/wizard/project_share_wizard.py b/addons/project/wizard/project_share_wizard.py index 8aae1700394..0a83e09bfca 100644 --- a/addons/project/wizard/project_share_wizard.py +++ b/addons/project/wizard/project_share_wizard.py @@ -39,10 +39,9 @@ class ProjectShareWizard(models.TransientModel): self.ensure_one() if self.access_mode == 'edit': portal_partners = self.partner_ids.filtered('user_ids') - note = self._get_note() self.resource_ref._add_collaborators(self.partner_ids) - self._send_public_link(note, portal_partners) - self._send_signup_link(note, partners=self.partner_ids - portal_partners) + self._send_public_link(portal_partners) + self._send_signup_link(partners=self.partner_ids - portal_partners) self.resource_ref.message_subscribe(partner_ids=self.partner_ids.ids) return {'type': 'ir.actions.act_window_close'} return super().action_send_mail() diff --git a/addons/purchase/models/purchase.py b/addons/purchase/models/purchase.py index 463b6472f6e..d8ff5c665ef 100644 --- a/addons/purchase/models/purchase.py +++ b/addons/purchase/models/purchase.py @@ -750,7 +750,11 @@ class PurchaseOrder(models.Model): if send_single: return order._send_reminder_open_composer(template.id) else: - order.with_context(is_reminder=True).message_post_with_template(template.id, email_layout_xmlid="mail.mail_notification_layout_with_responsible_signature", composition_mode='comment') + order.with_context(is_reminder=True).message_post_with_template( + template.id, + email_layout_xmlid="mail.mail_notification_layout_with_responsible_signature", + subtype_xmlid='mail.mt_comment', + ) def send_reminder_preview(self): self.ensure_one() @@ -1100,9 +1104,11 @@ class PurchaseOrderLine(models.Model): if 'product_qty' in values: for line in self: if line.order_id.state == 'purchase': - line.order_id.message_post_with_view('purchase.track_po_line_template', - values={'line': line, 'product_qty': values['product_qty']}, - subtype_id=self.env.ref('mail.mt_note').id) + line.order_id.message_post_with_view( + 'purchase.track_po_line_template', + values={'line': line, 'product_qty': values['product_qty']}, + subtype_xmlid='mail.mt_note', + ) if 'qty_received' in values: for line in self: line._track_qty_received(values['qty_received']) @@ -1422,7 +1428,7 @@ class PurchaseOrderLine(models.Model): self.order_id.message_post_with_view( 'purchase.track_po_line_qty_received_template', values={'line': self, 'qty_received': new_qty}, - subtype_id=self.env.ref('mail.mt_note').id + subtype_xmlid='mail.mt_note', ) def _validate_analytic_distribution(self): diff --git a/addons/purchase_requisition/models/purchase.py b/addons/purchase_requisition/models/purchase.py index 153e3c1beae..9f36e77e47b 100644 --- a/addons/purchase_requisition/models/purchase.py +++ b/addons/purchase_requisition/models/purchase.py @@ -142,13 +142,13 @@ class PurchaseOrder(models.Model): origin_po_id.purchase_group_id.order_ids |= orders else: self.env['purchase.order.group'].create({'order_ids': [Command.set(origin_po_id.ids + orders.ids)]}) - mt_note = self.env['ir.model.data']._xmlid_to_res_id('mail.mt_note') for order in orders: if order.requisition_id: order.message_post_with_view( 'mail.message_origin_link', values={'self': order, 'origin': order.requisition_id}, - subtype_id=mt_note) + subtype_xmlid='mail.mt_note', + ) return orders def write(self, vals): @@ -161,7 +161,7 @@ class PurchaseOrder(models.Model): order.message_post_with_view( 'mail.message_origin_link', values={'self': order, 'origin': order.requisition_id, 'edit': True}, - subtype_id=self.env['ir.model.data']._xmlid_to_res_id('mail.mt_note') + subtype_xmlid='mail.mt_note', ) if vals.get('alternative_po_ids', False): if not self.purchase_group_id and len(self.alternative_po_ids + self) > len(self): diff --git a/addons/purchase_stock/models/purchase.py b/addons/purchase_stock/models/purchase.py index 71b69036781..0ce54cb39ab 100644 --- a/addons/purchase_stock/models/purchase.py +++ b/addons/purchase_stock/models/purchase.py @@ -253,7 +253,8 @@ class PurchaseOrder(models.Model): (pickings | forward_pickings).action_confirm() picking.message_post_with_view('mail.message_origin_link', values={'self': picking, 'origin': order}, - subtype_id=self.env.ref('mail.mt_note').id) + subtype_xmlid='mail.mt_note', + ) return True def _add_picking_info(self, activity): diff --git a/addons/rating/models/rating_mixin.py b/addons/rating/models/rating_mixin.py index ac2e11e47b3..6c60ecda73a 100644 --- a/addons/rating/models/rating_mixin.py +++ b/addons/rating/models/rating_mixin.py @@ -185,7 +185,7 @@ class RatingMixin(models.AbstractModel): record.message_post_with_template( template.id, email_layout_xmlid='mail.mail_notification_light', - subtype_id=self.env['ir.model.data']._xmlid_to_res_id('mail.mt_note'), + subtype_xmlid='mail.mt_note', ) def rating_apply(self, rate, token=None, rating=None, feedback=None, @@ -223,7 +223,7 @@ class RatingMixin(models.AbstractModel): if subtype_xmlid is None: subtype_id = self._rating_apply_get_default_subtype_id() else: - subtype_id = self.env['ir.model.data']._xmlid_to_res_id(subtype_xmlid) + subtype_id = False feedback = tools.plaintext2html(feedback or '') scheduled_datetime = ( @@ -249,6 +249,7 @@ class RatingMixin(models.AbstractModel): rating_id=rating.id, scheduled_date=scheduled_datetime, subtype_id=subtype_id, + subtype_xmlid=subtype_xmlid, ) return rating diff --git a/addons/sale/models/payment_transaction.py b/addons/sale/models/payment_transaction.py index 6567b9ede01..a5364d45a2e 100644 --- a/addons/sale/models/payment_transaction.py +++ b/addons/sale/models/payment_transaction.py @@ -125,9 +125,10 @@ class PaymentTransaction(models.Model): return super()._reconcile_after_done() def _send_invoice(self): - template_id = self.env['ir.config_parameter'].sudo().get_param( - 'sale.default_invoice_email_template' - ) + template_id = int(self.env['ir.config_parameter'].sudo().get_param( + 'sale.default_invoice_email_template', + default=0 + )) if not template_id: return @@ -141,8 +142,9 @@ class PaymentTransaction(models.Model): invoice_to_send.is_move_sent = True # Mark invoice as sent for invoice in invoice_to_send.with_user(SUPERUSER_ID): invoice.message_post_with_template( - int(template_id), + template_id, email_layout_xmlid='mail.mail_notification_layout_with_responsible_signature', + subtype_xmlid='mail.mt_comment', ) def _cron_send_invoice(self): diff --git a/addons/sale/models/sale_order.py b/addons/sale/models/sale_order.py index e7e42a0335f..caa59ffa6b4 100644 --- a/addons/sale/models/sale_order.py +++ b/addons/sale/models/sale_order.py @@ -844,8 +844,8 @@ class SaleOrder(models.Model): continue sale_order.with_context(force_send=True).message_post_with_template( mail_template.id, - composition_mode='comment', email_layout_xmlid='mail.mail_notification_layout_with_responsible_signature', + subtype_xmlid='mail.mt_comment', ) def action_done(self): @@ -1184,7 +1184,8 @@ class SaleOrder(models.Model): move.message_post_with_view( 'mail.message_origin_link', values={'self': move, 'origin': move.line_ids.sale_line_ids.order_id}, - subtype_id=self.env['ir.model.data']._xmlid_to_res_id('mail.mt_note')) + subtype_xmlid='mail.mt_note', + ) return moves # MAIL # diff --git a/addons/sale/tests/test_controllers.py b/addons/sale/tests/test_controllers.py index 91bcedb3ae2..5c828e479bf 100644 --- a/addons/sale/tests/test_controllers.py +++ b/addons/sale/tests/test_controllers.py @@ -88,6 +88,8 @@ class TestSaleSignature(HttpCaseWithUserPortal): email_act = sales_order.action_quotation_send() email_ctx = email_act.get('context', {}) sales_order.with_context(**email_ctx).message_post_with_template( - email_ctx.get('default_template_id')) + email_ctx.get('default_template_id'), + subtype_xmlid='mail.mt_comment', + ) self.start_tour("/", 'sale_signature', login="portal") diff --git a/addons/sale/tests/test_sale_order.py b/addons/sale/tests/test_sale_order.py index 5a7442859c6..aa38876de75 100644 --- a/addons/sale/tests/test_sale_order.py +++ b/addons/sale/tests/test_sale_order.py @@ -79,7 +79,10 @@ class TestSaleOrder(SaleCommon): # send quotation email_act = self.sale_order.action_quotation_send() email_ctx = email_act.get('context', {}) - self.sale_order.with_context(**email_ctx).message_post_with_template(email_ctx.get('default_template_id')) + self.sale_order.with_context(**email_ctx).message_post_with_template( + email_ctx.get('default_template_id'), + subtype_xmlid='mail.mt_comment', + ) self.assertTrue(self.sale_order.state == 'sent', 'Sale: state after sending is wrong') self.sale_order.order_line._compute_product_updatable() self.assertTrue(self.sale_order.order_line[0].product_updatable) @@ -101,7 +104,10 @@ class TestSaleOrder(SaleCommon): # sent to to author or not (in case author is present in 'Recipients' of composer). mail_template = self.env['mail.template'].browse(email_ctx.get('default_template_id')).copy({'auto_delete': False}) # send the mail with same user as customer - sale_order.with_context(**email_ctx).with_user(self.sale_user).message_post_with_template(mail_template.id) + sale_order.with_context(**email_ctx).with_user(self.sale_user).message_post_with_template( + mail_template.id, + subtype_xmlid='mail.mt_comment', + ) self.assertTrue(sale_order.state == 'sent', 'Sale : state should be changed to sent') mail_message = sale_order.message_ids[0] self.assertEqual(mail_message.author_id, sale_order.partner_id, 'Sale: author should be same as customer') diff --git a/addons/sale/tests/test_sale_to_invoice.py b/addons/sale/tests/test_sale_to_invoice.py index 400909fd986..c205ae94fc6 100644 --- a/addons/sale/tests/test_sale_to_invoice.py +++ b/addons/sale/tests/test_sale_to_invoice.py @@ -632,7 +632,10 @@ class TestSaleToInvoice(TestSaleCommon): # send quotation email_act = self.sale_order.action_quotation_send() email_ctx = email_act.get('context', {}) - self.sale_order.with_context(**email_ctx).message_post_with_template(email_ctx.get('default_template_id')) + self.sale_order.with_context(**email_ctx).message_post_with_template( + email_ctx.get('default_template_id'), + subtype_xmlid='mail.mt_comment', + ) self.assertTrue(self.sale_order.state == 'sent', 'Sale: state after sending is wrong') self.sale_order.order_line._compute_product_updatable() self.assertTrue(self.sale_order.order_line[0].product_updatable) diff --git a/addons/sale/wizard/sale_make_invoice_advance.py b/addons/sale/wizard/sale_make_invoice_advance.py index 9e08b621421..7382c645c14 100644 --- a/addons/sale/wizard/sale_make_invoice_advance.py +++ b/addons/sale/wizard/sale_make_invoice_advance.py @@ -189,7 +189,8 @@ class SaleAdvancePaymentInv(models.TransientModel): invoice.message_post_with_view( 'mail.message_origin_link', values={'self': invoice, 'origin': order}, - subtype_id=self.env.ref('mail.mt_note').id) + subtype_xmlid='mail.mt_note', + ) return invoice diff --git a/addons/sale_stock/models/stock.py b/addons/sale_stock/models/stock.py index 43d6895efd0..6fb7d1db1dc 100644 --- a/addons/sale_stock/models/stock.py +++ b/addons/sale_stock/models/stock.py @@ -45,7 +45,8 @@ class StockMove(models.Model): picking_id.message_post_with_view( 'mail.message_origin_link', values={'self': picking_id, 'origin': sale_order_id}, - subtype_id=self.env.ref('mail.mt_note').id) + subtype_xmlid='mail.mt_note', + ) class ProcurementGroup(models.Model): diff --git a/addons/stock/models/stock_move_line.py b/addons/stock/models/stock_move_line.py index 7be9f3ccf34..1e57a205494 100644 --- a/addons/stock/models/stock_move_line.py +++ b/addons/stock/models/stock_move_line.py @@ -667,7 +667,11 @@ class StockMoveLine(models.Model): data['result_package_name'] = self.env['stock.quant.package'].browse(vals.get('result_package_id')).name if 'owner_id' in vals and vals['owner_id'] != move.owner_id.id: data['owner_name'] = self.env['res.partner'].browse(vals.get('owner_id')).name - record.message_post_with_view(template, values={'move': move, 'vals': dict(vals, **data)}, subtype_id=self.env.ref('mail.mt_note').id) + record.message_post_with_view( + template, + values={'move': move, 'vals': dict(vals, **data)}, + subtype_xmlid='mail.mt_note', + ) def _free_reservation(self, product_id, location_id, quantity, lot_id=None, package_id=None, owner_id=None, ml_ids_to_ignore=None): """ When editing a done move line or validating one with some forced quantities, it is diff --git a/addons/stock/models/stock_picking.py b/addons/stock/models/stock_picking.py index 79730a6ab77..bf3668979f7 100644 --- a/addons/stock/models/stock_picking.py +++ b/addons/stock/models/stock_picking.py @@ -884,9 +884,14 @@ class Picking(models.Model): return True def _send_confirmation_email(self): + subtype_id = self.env['ir.model.data']._xmlid_to_res_id('mail.mt_comment') for stock_pick in self.filtered(lambda p: p.company_id.stock_move_email_validation and p.picking_type_id.code == 'outgoing'): delivery_template_id = stock_pick.company_id.stock_mail_confirmation_template_id.id - stock_pick.with_context(force_send=True).message_post_with_template(delivery_template_id, email_layout_xmlid='mail.mail_notification_light') + stock_pick.with_context(force_send=True).message_post_with_template( + delivery_template_id, + email_layout_xmlid='mail.mail_notification_light', + subtype_id=subtype_id, + ) @api.depends('state', 'move_ids', 'move_ids.state', 'move_ids.package_level_id', 'move_ids.move_line_ids.package_level_id') def _compute_move_without_package(self): diff --git a/addons/stock/wizard/stock_picking_return.py b/addons/stock/wizard/stock_picking_return.py index 241dadf28eb..1b78158de32 100644 --- a/addons/stock/wizard/stock_picking_return.py +++ b/addons/stock/wizard/stock_picking_return.py @@ -133,9 +133,11 @@ class ReturnPicking(models.TransientModel): # create new picking for returned products new_picking = self.picking_id.copy(self._prepare_picking_default_values()) picking_type_id = new_picking.picking_type_id.id - new_picking.message_post_with_view('mail.message_origin_link', + new_picking.message_post_with_view( + 'mail.message_origin_link', values={'self': new_picking, 'origin': self.picking_id}, - subtype_id=self.env.ref('mail.mt_note').id) + subtype_xmlid='mail.mt_note', + ) returned_lines = 0 for return_line in self.product_return_moves: if not return_line.move_id: diff --git a/addons/test_mail/models/test_mail_models.py b/addons/test_mail/models/test_mail_models.py index c068b334d1e..60976cb9c9f 100644 --- a/addons/test_mail/models/test_mail_models.py +++ b/addons/test_mail/models/test_mail_models.py @@ -144,9 +144,21 @@ class MailTestTicket(models.Model): res = super(MailTestTicket, self)._track_template(changes) record = self[0] if 'customer_id' in changes and record.mail_template: - res['customer_id'] = (record.mail_template, {'composition_mode': 'mass_mail'}) + res['customer_id'] = ( + record.mail_template, + { + 'composition_mode': 'mass_mail', + 'subtype_id': self.env['ir.model.data']._xmlid_to_res_id('mail.mt_note'), + } + ) elif 'datetime' in changes: - res['datetime'] = ('test_mail.mail_test_ticket_tracking_view', {'composition_mode': 'mass_mail'}) + res['datetime'] = ( + 'test_mail.mail_test_ticket_tracking_view', + { + 'composition_mode': 'mass_mail', + 'subtype_id': self.env['ir.model.data']._xmlid_to_res_id('mail.mt_note'), + } + ) return res def _creation_subtype(self): diff --git a/addons/test_mail/static/tests/activity_tests.js b/addons/test_mail/static/tests/activity_tests.js index af7f07571b0..7ee548a2915 100644 --- a/addons/test_mail/static/tests/activity_tests.js +++ b/addons/test_mail/static/tests/activity_tests.js @@ -351,6 +351,7 @@ QUnit.module("test_mail", {}, function () { { default_model: "mail.test.activity", default_res_id: mailTestActivityId2, + default_subtype_xmlid: 'mail.mt_comment', default_template_id: mailTemplateId1, default_use_template: true, force_email: true, diff --git a/addons/test_mail/tests/test_mail_composer.py b/addons/test_mail/tests/test_mail_composer.py index a7804129349..dfabe4cb5d7 100644 --- a/addons/test_mail/tests/test_mail_composer.py +++ b/addons/test_mail/tests/test_mail_composer.py @@ -1106,6 +1106,16 @@ class TestComposerResultsComment(TestMailComposer): _mail, message = composer._action_send_mail() self.assertEqual(message.subtype_id, self.env.ref('mail.mt_note')) + # subtype through xml id + composer = self.env['mail.compose.message'].with_context( + self._get_web_context(self.test_record), + default_subtype_xmlid='mail.mt_note', + ).create({ + 'body': '

Default subtype through xml id

', + }) + _mail, message = composer._action_send_mail() + self.assertEqual(message.subtype_id, self.env.ref('mail.mt_note')) + @users('employee') @mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink') def test_mail_composer_recipients(self): diff --git a/addons/test_mail/tests/test_message_post.py b/addons/test_mail/tests/test_message_post.py index eaf18c15b14..a05a89a8554 100644 --- a/addons/test_mail/tests/test_message_post.py +++ b/addons/test_mail/tests/test_message_post.py @@ -1007,6 +1007,7 @@ class TestMessagePostHelpers(TestMessagePostCommon): _new_mails, _new_messages = test_records.with_user(self.user_employee).message_post_with_template( template.id, composition_mode='mass_mail', + subtype_id=self.env['ir.model.data']._xmlid_to_res_id('mail.mt_note'), ) # created partners from inline email addresses @@ -1056,6 +1057,7 @@ class TestMessagePostHelpers(TestMessagePostCommon): values={'partner': self.user_employee.partner_id}, composition_mode='mass_mail', subject='About mass mailing', + subtype_id=self.env['ir.model.data']._xmlid_to_res_id('mail.mt_note'), ) self.assertEqual(len(new_messages), 0) self.assertEqual(len(self._new_mails), 10) @@ -1351,7 +1353,7 @@ class TestMessagePostLang(TestMailCommon, TestRecipients): composition_mode='mass_mail', email_layout_xmlid='mail.test_layout', message_type='comment', - subtype_id=self.env.ref('mail.mt_comment').id, + subtype_id=self.env['ir.model.data']._xmlid_to_res_id('mail.mt_comment'), ) record0_customer = self.env['res.partner'].search([('email_normalized', '=', 'test.record.1@test.customer.com')], limit=1) @@ -1417,7 +1419,7 @@ class TestMessagePostLang(TestMailCommon, TestRecipients): test_template.id, email_layout_xmlid='mail.test_layout', message_type='comment', - subtype_id=self.env.ref('mail.mt_comment').id, + subtype_id=self.env['ir.model.data']._xmlid_to_res_id('mail.mt_comment'), ) record0_customer = self.env['res.partner'].search([('email_normalized', '=', 'test.record.1@test.customer.com')], limit=1) diff --git a/addons/test_mail/tests/test_performance.py b/addons/test_mail/tests/test_performance.py index 1f37ef5fcba..956661d8007 100644 --- a/addons/test_mail/tests/test_performance.py +++ b/addons/test_mail/tests/test_performance.py @@ -866,7 +866,12 @@ class TestMailComplexPerformance(BaseMailPerformance): # about 20 (19 ?) queries per additional customer group with self.assertQueryCount(__system__=42, employee=43): - record.message_post_with_template(template_id, message_type='comment', composition_mode='comment') + record.message_post_with_template( + template_id, + message_type='comment', + composition_mode='comment', + subtype_id=self.env['ir.model.data']._xmlid_to_res_id('mail.mt_comment'), + ) self.assertEqual(record.message_ids[0].body, '

Adding stuff on %s

' % record.name) self.assertEqual(record.message_ids[0].notified_partner_ids, self.partners | self.user_portal.partner_id | self.customer) @@ -890,6 +895,7 @@ class TestMailComplexPerformance(BaseMailPerformance): messages_as_sudo = test_records.message_post_with_view( 'test_mail.mail_template_simple_test', values={'partner': self.user_test.partner_id}, + subtype_id=self.env['ir.model.data']._xmlid_to_res_id('mail.mt_comment') ) self.assertEqual(len(messages_as_sudo), 10) diff --git a/addons/website_blog/models/website_blog.py b/addons/website_blog/models/website_blog.py index 34f73237214..d9c58799622 100644 --- a/addons/website_blog/models/website_blog.py +++ b/addons/website_blog/models/website_blog.py @@ -225,7 +225,8 @@ class BlogPost(models.Model): 'website_blog.blog_post_template_new_post', subject=post.name, values={'post': post}, - subtype_id=self.env['ir.model.data']._xmlid_to_res_id('website_blog.mt_blog_blog_published')) + subtype_xmlid='website_blog.mt_blog_blog_published', + ) return True return False diff --git a/addons/website_crm_iap_reveal/models/crm_reveal_rule.py b/addons/website_crm_iap_reveal/models/crm_reveal_rule.py index 33b3d0604ca..e4d35fa39b2 100644 --- a/addons/website_crm_iap_reveal/models/crm_reveal_rule.py +++ b/addons/website_crm_iap_reveal/models/crm_reveal_rule.py @@ -379,7 +379,7 @@ class CRMRevealRule(models.Model): lead.message_post_with_view( 'iap_mail.enrich_company', values=template_values, - subtype_id=self.env.ref('mail.mt_note').id + subtype_xmlid='mail.mt_note', ) return lead diff --git a/addons/website_event_track/models/event_track.py b/addons/website_event_track/models/event_track.py index bcc6dd8f77e..fe6df7e6681 100644 --- a/addons/website_event_track/models/event_track.py +++ b/addons/website_event_track/models/event_track.py @@ -404,16 +404,16 @@ class Track(models.Model): tracks = super(Track, self).create(vals_list) + post_values = {} if self.env.user.email else {'email_from': self.env.company.catchall_formatted} for track in tracks: - email_values = {} if self.env.user.email else {'email_from': self.env.company.catchall_formatted} track.event_id.message_post_with_view( 'website_event_track.event_track_template_new', values={ 'track': track, 'is_html_empty': is_html_empty, }, - subtype_id=self.env.ref('website_event_track.mt_event_track').id, - **email_values, + subtype_xmlid='website_event_track.mt_event_track', + **post_values, ) track._synchronize_with_stage(track.stage_id) @@ -492,10 +492,10 @@ class Track(models.Model): track = self[0] if 'stage_id' in changes and track.stage_id.mail_template_id: res['stage_id'] = (track.stage_id.mail_template_id, { - 'composition_mode': 'comment', 'auto_delete_message': True, + 'composition_mode': 'comment', + 'email_layout_xmlid': 'mail.mail_notification_light', 'subtype_id': self.env['ir.model.data']._xmlid_to_res_id('mail.mt_note'), - 'email_layout_xmlid': 'mail.mail_notification_light' }) return res diff --git a/addons/website_forum/models/forum.py b/addons/website_forum/models/forum.py index c707dccf3ee..6f49b658f58 100644 --- a/addons/website_forum/models/forum.py +++ b/addons/website_forum/models/forum.py @@ -627,13 +627,15 @@ class Post(models.Model): 'website_forum.forum_post_template_new_answer', subject=_('Re: %s', post.parent_id.name), partner_ids=[(4, p.id) for p in tag_partners], - subtype_id=self.env['ir.model.data']._xmlid_to_res_id('website_forum.mt_answer_new')) + subtype_xmlid='website_forum.mt_answer_new', + ) elif post.state == 'active' and not post.parent_id: post.message_post_with_view( 'website_forum.forum_post_template_new_question', subject=post.name, partner_ids=[(4, p.id) for p in tag_partners], - subtype_id=self.env['ir.model.data']._xmlid_to_res_id('website_forum.mt_question_new')) + subtype_xmlid='website_forum.mt_question_new', + ) elif post.state == 'pending' and not post.parent_id: # TDE FIXME: in master, you should probably use a subtype; # however here we remove subtype but set partner_ids @@ -644,7 +646,8 @@ class Post(models.Model): 'website_forum.forum_post_template_validation', subject=post.name, partner_ids=partners.ids, - subtype_id=self.env['ir.model.data']._xmlid_to_res_id('mail.mt_note')) + subtype_xmlid='mail.mt_note', + ) return True def reopen(self):