From 00ebf747af985a1d13e8c63164f9f4e64555eb7c Mon Sep 17 00:00:00 2001 From: Renaud Thiry Date: Wed, 28 Feb 2024 16:08:53 +0000 Subject: [PATCH] [FIX] mail: add selection when fetching message type A new message type was added in stable. This is usually safe, however in cases where there are related fields on that same selection fetching them will raise an exception as the ORM has to fetch the translations for the selection in DB. We add a hack on mail.mail to update the selections in DB when fetching the message_type field for the first time. task-3773301 closes odoo/odoo#156235 X-original-commit: 19683173708a2b029acb4e744871772b6c248715 Signed-off-by: Thibault Delavallee (tde) Signed-off-by: Renaud Thiry (reth) --- addons/mail/models/mail_mail.py | 18 ++++++++++++++++++ addons/mail/tests/__init__.py | 1 + .../tests/test_mail_mail_stable_selection.py | 16 ++++++++++++++++ 3 files changed, 35 insertions(+) create mode 100644 addons/mail/tests/test_mail_mail_stable_selection.py diff --git a/addons/mail/models/mail_mail.py b/addons/mail/models/mail_mail.py index aa3454abef4..5225587dfa3 100644 --- a/addons/mail/models/mail_mail.py +++ b/addons/mail/models/mail_mail.py @@ -122,6 +122,24 @@ class MailMail(models.Model): def _search_body_content(self, operator, value): return [('body_html', operator, value)] + @api.model + def fields_get(self, *args, **kwargs): + # related selection will fetch translations from DB + # selections added in stable won't be in DB -> add them on the related model if not already added + message_type_field = self.env['mail.message']._fields['message_type'] + if 'auto_comment' not in {value for value, name in message_type_field.get_description(self.env)['selection']}: + self._fields_get_message_type_update_selection(message_type_field.selection) + return super().fields_get(*args, **kwargs) + + def _fields_get_message_type_update_selection(self, selection): + """Update the field selection for message type on mail.message to match the runtime values. + + DO NOT USE it is only there for a stable fix and should not be used for any reason other than hotfixing. + """ + self.env['ir.model.fields'].invalidate_model(['selection_ids']) + self.env['ir.model.fields.selection'].sudo()._update_selection('mail.message', 'message_type', selection) + self.env.registry.clear_cache() + @api.model_create_multi def create(self, values_list): # notification field: if not set, set if mail comes from an existing mail.message diff --git a/addons/mail/tests/__init__.py b/addons/mail/tests/__init__.py index 17f70442d80..5b62327f761 100644 --- a/addons/mail/tests/__init__.py +++ b/addons/mail/tests/__init__.py @@ -4,6 +4,7 @@ from . import test_ir_mail_server from . import test_link_preview from . import test_mail_activity from . import test_mail_composer +from . import test_mail_mail_stable_selection from . import test_mail_render from . import test_mail_template from . import test_mail_tools diff --git a/addons/mail/tests/test_mail_mail_stable_selection.py b/addons/mail/tests/test_mail_mail_stable_selection.py new file mode 100644 index 00000000000..61e49508597 --- /dev/null +++ b/addons/mail/tests/test_mail_mail_stable_selection.py @@ -0,0 +1,16 @@ + + +from odoo.tests.common import TransactionCase + +class TestMailMailStableSelection(TransactionCase): + """Only relevant in stable as a hotfix. May be removed in master.""" + + def test_mail_mail_stable_selection(self): + # remove all selections + message_type_selections = self.env['ir.model.fields']._get('mail.message', 'message_type').selection_ids + message_type_selections.filtered(lambda s: s.value == 'auto_comment').unlink() + self.env['mail.mail']._fields_get_message_type_update_selection(self.env['mail.message']._fields['message_type'].selection) + # force convert to cache with specific language so it has to fetch related from DB + mail = self.env['mail.mail'].create({'subject': 'test', 'message_type': 'auto_comment'}) + mail.invalidate_recordset(['message_type']) + self.assertEqual(mail.with_context(lang="en_US").message_type, 'auto_comment')