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 @@
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):