diff options
Diffstat (limited to 'addons')
| -rw-r--r-- | addons/account/models/account_move.py | 10 | ||||
| -rw-r--r-- | addons/hr/models/__init__.py | 1 | ||||
| -rw-r--r-- | addons/hr/models/mail_alias.py | 21 | ||||
| -rw-r--r-- | addons/hr/models/models.py | 20 | ||||
| -rw-r--r-- | addons/mail/models/mail_alias_mixin.py | 21 | ||||
| -rw-r--r-- | addons/mail/models/mail_channel.py | 4 | ||||
| -rw-r--r-- | addons/mail/models/mail_message.py | 6 | ||||
| -rw-r--r-- | addons/mail/models/mail_template.py | 2 | ||||
| -rw-r--r-- | addons/mail/models/mail_thread.py | 159 | ||||
| -rw-r--r-- | addons/mail/models/models.py | 170 | ||||
| -rw-r--r-- | addons/mail/wizard/mail_compose_message.py | 4 |
11 files changed, 220 insertions, 198 deletions
diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py index 99f6195d4f6..7bfff747fdd 100644 --- a/addons/account/models/account_move.py +++ b/addons/account/models/account_move.py @@ -3713,16 +3713,16 @@ class AccountMoveLine(models.Model): for move_id, modified_lines in move_initial_values.items(): tmp_move = {move_id: []} for line in self.filtered(lambda l: l.move_id.id == move_id): - tracked_field = self.env['mail.thread'].static_message_track(line, ref_fields, modified_lines) # Return a tuple like (changed field, ORM command) + changes, tracking_value_ids = line._mail_track(ref_fields, modified_lines) # Return a tuple like (changed field, ORM command) tmp = {'line_id': line.id} - if len(tracked_field[1]) > 0: - selected_field = tracked_field[1][0][2] # Get the last element of the tuple in the list of ORM command. (changed, [(0, 0, THIS)]) + if tracking_value_ids: + selected_field = tracking_value_ids[0][2] # Get the last element of the tuple in the list of ORM command. (changed, [(0, 0, THIS)]) tmp.update({ **{'field_name': selected_field.get('field_desc')}, **self._get_formated_values(selected_field) }) - elif len(tracked_field[0]): - field_name = line._fields[tracked_field[0].pop()].string # Get the field name + elif changes: + field_name = line._fields[changes.pop()].string # Get the field name tmp.update({ 'error': True, 'field_error': field_name diff --git a/addons/hr/models/__init__.py b/addons/hr/models/__init__.py index 1c06c535ae8..f9e64bc7013 100644 --- a/addons/hr/models/__init__.py +++ b/addons/hr/models/__init__.py @@ -10,6 +10,7 @@ from . import hr_job from . import hr_plan from . import mail_alias from . import mail_channel +from . import models from . import res_config_settings from . import res_partner from . import res_users diff --git a/addons/hr/models/mail_alias.py b/addons/hr/models/mail_alias.py index 3d652142f68..69042cfb1bd 100644 --- a/addons/hr/models/mail_alias.py +++ b/addons/hr/models/mail_alias.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo import fields, models, tools, _ +from odoo import fields, models, _ class Alias(models.Model): @@ -16,21 +16,4 @@ class Alias(models.Model): return _("""Hi,<br/> Your document has not been created because your email address is not recognized.<br/> Please send emails with the email address recorded on your employee information, or contact your HR manager.""") - else: - return super(Alias, self)._get_alias_bounced_body_fallback(message_dict) - - -class AliasMixin(models.AbstractModel): - _inherit = 'mail.alias.mixin' - - def _alias_check_contact_on_record(self, record, message, message_dict, alias): - if alias.alias_contact == 'employees': - email_from = tools.decode_message_header(message, 'From') - email_address = tools.email_split(email_from)[0] - employee = self.env['hr.employee'].search([('work_email', 'ilike', email_address)], limit=1) - if not employee: - employee = self.env['hr.employee'].search([('user_id.email', 'ilike', email_address)], limit=1) - if not employee: - return _('restricted to employees') - return True - return super(AliasMixin, self)._alias_check_contact_on_record(record, message, message_dict, alias) + return super(Alias, self)._get_alias_bounced_body_fallback(message_dict) diff --git a/addons/hr/models/models.py b/addons/hr/models/models.py new file mode 100644 index 00000000000..dd615798364 --- /dev/null +++ b/addons/hr/models/models.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import models, tools, _ + + +class BaseModel(models.AbstractModel): + _inherit = 'base' + + def _alias_get_error_message(self, message, message_dict, alias): + if alias.alias_contact == 'employees': + email_from = tools.decode_message_header(message, 'From') + email_address = tools.email_split(email_from)[0] + employee = self.env['hr.employee'].search([('work_email', 'ilike', email_address)], limit=1) + if not employee: + employee = self.env['hr.employee'].search([('user_id.email', 'ilike', email_address)], limit=1) + if not employee: + return _('restricted to employees') + return True + return super(BaseModel, self)._alias_get_error_message(message, message_dict, alias) diff --git a/addons/mail/models/mail_alias_mixin.py b/addons/mail/models/mail_alias_mixin.py index f753136669f..b06cd174a71 100644 --- a/addons/mail/models/mail_alias_mixin.py +++ b/addons/mail/models/mail_alias_mixin.py @@ -125,23 +125,6 @@ class AliasMixin(models.AbstractModel): # GATEWAY # -------------------------------------------------- - def _alias_check_contact(self, message, message_dict, alias): - """ Main mixin method that inheriting models may inherit in order - to implement a specifc behavior. """ - return self._alias_check_contact_on_record(self, message, message_dict, alias) - def _alias_check_contact_on_record(self, record, message, message_dict, alias): - """ Generic method that takes a record not necessarily inheriting from - mail.alias.mixin. """ - author = self.env['res.partner'].browse(message_dict.get('author_id', False)) - if alias.alias_contact == 'followers': - if not record.ids: - return _('incorrectly configured alias (unknown reference record)') - if not hasattr(record, "message_partner_ids") or not hasattr(record, "message_channel_ids"): - return _('incorrectly configured alias') - accepted_partner_ids = record.message_partner_ids | record.message_channel_ids.mapped('channel_partner_ids') - if not author or author not in accepted_partner_ids: - return _('restricted to followers') - elif alias.alias_contact == 'partners' and not author: - return _('restricted to known authors') - return True + """ Move to ``BaseModel._alias_get_error_message() """ + return record._alias_get_error_message(message, message_dict, alias) diff --git a/addons/mail/models/mail_channel.py b/addons/mail/models/mail_channel.py index 093c94878b4..d63b1ecf80b 100644 --- a/addons/mail/models/mail_channel.py +++ b/addons/mail/models/mail_channel.py @@ -386,13 +386,13 @@ class Channel(models.Model): }) return message - def _alias_check_contact(self, message, message_dict, alias): + def _alias_get_error_message(self, message, message_dict, alias): if alias.alias_contact == 'followers' and self.ids: author = self.env['res.partner'].browse(message_dict.get('author_id', False)) if not author or author not in self.channel_partner_ids: return _('restricted to channel members') return True - return super(Channel, self)._alias_check_contact(message, message_dict, alias) + return super(Channel, self)._alias_get_error_message(message, message_dict, alias) def init(self): self._cr.execute('SELECT indexname FROM pg_indexes WHERE indexname = %s', ('mail_channel_partner_seen_message_id_idx',)) diff --git a/addons/mail/models/mail_message.py b/addons/mail/models/mail_message.py index f74596c1226..84b0976ed3e 100644 --- a/addons/mail/models/mail_message.py +++ b/addons/mail/models/mail_message.py @@ -1167,15 +1167,15 @@ class Message(models.Model): def _get_reply_to(self, values): """ Return a specific reply_to for the document """ model = values.get('model', self._context.get('default_model')) - res_id = values.get('res_id', self._context.get('default_res_id')) + res_id = values.get('res_id', self._context.get('default_res_id')) or False email_from = values.get('email_from') message_type = values.get('message_type') records = None if self.is_thread_message({'model': model, 'res_id': res_id, 'message_type': message_type}): records = self.env[model].browse([res_id]) else: - res_id = False - return self.env['mail.thread']._notify_get_reply_to_on_records(default=email_from, records=records)[res_id] + records = self.env[model] if model else self.env['mail.thread'] + return records._notify_get_reply_to(default=email_from)[res_id] @api.model def _get_message_id(self, values): diff --git a/addons/mail/models/mail_template.py b/addons/mail/models/mail_template.py index 92783104b65..e0d3c30490e 100644 --- a/addons/mail/models/mail_template.py +++ b/addons/mail/models/mail_template.py @@ -116,7 +116,7 @@ class MailTemplate(models.Model): if self.use_default_to or self._context.get('tpl_force_default_to'): records = self.env[self.model].browse(res_ids).sudo() - default_recipients = self.env['mail.thread']._message_get_default_recipients_on_records(records) + default_recipients = records._message_get_default_recipients() for res_id, recipients in default_recipients.items(): results[res_id].pop('partner_to', None) results[res_id].update(recipients) diff --git a/addons/mail/models/mail_thread.py b/addons/mail/models/mail_thread.py index 22497352bec..3a9c68db2a9 100644 --- a/addons/mail/models/mail_thread.py +++ b/addons/mail/models/mail_thread.py @@ -583,38 +583,6 @@ class MailThread(models.AbstractModel): def _track_template(self, changes): return dict() - @api.model - def static_message_track(self, record, tracked_fields, initial): - """ For a given record, fields to check (tuple column name, column info) - and initial values, return a structure that is a tuple containing : - - a set of updated column names - - a list of ORM (0, 0, values) commands to create 'mail.tracking.value' - This static method is usefull when you don't want to inherit from mail.thread but - you want to use '_message_track()' method. - """ - record.ensure_one() - changes = set() # contains onchange tracked fields that changed - tracking_value_ids = [] - - # generate tracked_values data structure: {'col_name': {col_info, new_value, old_value}} - for col_name, col_info in tracked_fields.items(): - if col_name not in initial: - continue - initial_value = initial[col_name] - new_value = record[col_name] - - if new_value != initial_value and (new_value or initial_value): # because browse null != False - tracking_sequence = getattr(record._fields[col_name], 'tracking', - getattr(record._fields[col_name], 'track_sequence', 100)) # backward compatibility with old parameter name - if tracking_sequence is True: - tracking_sequence = 100 - tracking = record.env['mail.tracking.value'].create_tracking_values(initial_value, new_value, col_name, col_info, tracking_sequence, record._name) - if tracking: - tracking_value_ids.append([0, 0, tracking]) - changes.add(col_name) - - return changes, tracking_value_ids - def message_track(self, tracked_fields, initial_values): """ Track updated values. Comparing the initial and current values of the fields given in tracked_fields, it generates a message containing @@ -657,12 +625,13 @@ class MailThread(models.AbstractModel): return tracking + def static_message_track(self, record, tracked_fields, initial): + """ Deprecated, remove in v14+ """ + return record._mail_track(tracked_fields, initial) + def _message_track(self, tracked_fields, initial): - """ For a given record, fields to check (tuple column name, column info) - and initial values, return a structure that is a tuple containing : - - a set of updated column names - - a list of ORM (0, 0, values) commands to create 'mail.tracking.value' """ - return self.static_message_track(self, tracked_fields, initial) + """ Moved to ``BaseModel._mail_track()`` """ + return self._mail_track(tracked_fields, initial) def _track_subtype(self, init_values): """ Give the subtypes triggered by the changes on the record according @@ -844,13 +813,10 @@ class MailThread(models.AbstractModel): obj = self.env[alias.alias_parent_model_id.model].browse(alias.alias_parent_thread_id) else: obj = self.env[model] - if hasattr(obj, '_alias_check_contact'): - error_code = obj._alias_check_contact(message, message_dict, alias) - else: - error_code = self.env['mail.alias.mixin']._alias_check_contact_on_record(obj, message, message_dict, alias) - if error_code is not True: + error_message = obj._alias_get_error_message(message, message_dict, alias) + if error_message: self._routing_warn( - _('alias %(name)s: %(error)s', name=alias.alias_name, error=error_code or _('unknown error')), + _('alias %(name)s: %(error)s', name=alias.alias_name, error=error_message or _('unknown error')), message_id, route, False @@ -1491,27 +1457,8 @@ class MailThread(models.AbstractModel): @api.model def _message_get_default_recipients_on_records(self, records): - """ Generic implementation for finding default recipient to mail on - a recordset. ``_message_get_default_recipients`` may be defined to - implement custom behavior. """ - if hasattr(records, '_message_get_default_recipients'): - return records._message_get_default_recipients() - - res = {} - for record in records: - recipient_ids, email_to, email_cc = [], False, False - if 'partner_id' in record and record.partner_id: - recipient_ids.append(record.partner_id.id) - elif 'email_normalized' in record and record.email_normalized: - email_to = record.email_normalized - elif 'email_from' in record and record.email_from: - email_to = record.email_from - elif 'partner_email' in record and record.partner_email: - email_to = record.partner_email - elif 'email' in record and record.email: - email_to = record.email - res[record.id] = {'partner_ids': recipient_ids, 'email_to': email_to, 'email_cc': email_cc} - return res + """ Moved to ``BaseModel._message_get_default_recipients()`` """ + return records._message_get_default_recipients() def _message_add_suggested_recipient(self, result, partner=None, email=None, reason=''): """ Called by _message_get_suggested_recipients, to add a suggested @@ -2646,89 +2593,11 @@ class MailThread(models.AbstractModel): return result - def _notify_get_reply_to(self, default=None, records=None, company=None, doc_names=None): - """ Returns the preferred reply-to email address when replying to a thread - on documents. Documents are either given by self it this method is called - as a true multi method on a record set or can be given using records to - have a generic implementation available for all models. - Reply-to is formatted like "MyCompany MyDocument <reply.to@domain>". - Heuristic it the following: - * search for specific aliases as they always have priority; it is limited - to aliases linked to documents (like project alias for task for example); - * use catchall address; - * use default; - This method works on documents - * as a true multi method for models inheriting from mail.thread; call - ``records._notify_get_reply_to(...)``; - * as a generic implementation if records are given; call ``MailThread. - _notify_get_reply_to(records=records, ...)``; - * as a generic implementation is self is a void mail.thread record set - meaning catchall is computed; call ``MailThread._notify_get_reply_to - (records=None)``; - Tweak this method on a specific model by overriding if it inherits from - mail.thread. An example would be tasks taking their reply-to alias from - their project. - :param default: default email if no alias or catchall is found; - :param records: record_set if self if a generic mail.thread record allowing - generic implementation of finding reply-to; - :param company: used to compute company name part of the from name; provide - it if already known, otherwise fall back on user company; - :param doc_names: dict(res_id, doc_name) used to compute doc name part of - the from name; provide it if already known to avoid queries, otherwise - name_get on document will be performed; - :return result: dictionary. Keys are record IDs and value is formatted - like an email "Company_name Document_name <reply_to@email>"/ - """ - _records = self if self and self._name != 'mail.thread' else records - model = _records._name if _records and _records._name != 'mail.thread' else False - res_ids = _records.ids if _records and model else [] - _res_ids = res_ids or [False] # always have a default value located in False - - alias_domain = self.env['ir.config_parameter'].sudo().get_param("mail.catchall.domain") - result = dict.fromkeys(_res_ids, False) - result_email = dict() - doc_names = doc_names if doc_names else dict() - - if alias_domain: - if model and res_ids: - if not doc_names: - doc_names = dict((rec.id, rec.display_name) for rec in _records) - - mail_aliases = self.env['mail.alias'].sudo().search([ - ('alias_parent_model_id.model', '=', model), - ('alias_parent_thread_id', 'in', res_ids), - ('alias_name', '!=', False)]) - # take only first found alias for each thread_id, to match order (1 found -> limit=1 for each res_id) - for alias in mail_aliases: - result_email.setdefault(alias.alias_parent_thread_id, '%s@%s' % (alias.alias_name, alias_domain)) - - # left ids: use catchall - left_ids = set(_res_ids) - set(result_email) - if left_ids: - catchall = self.env['ir.config_parameter'].sudo().get_param("mail.catchall.alias") - if catchall: - result_email.update(dict((rid, '%s@%s' % (catchall, alias_domain)) for rid in left_ids)) - - # compute name of reply-to - TDE tocheck: quotes and stuff like that - company_name = company.name if company else self.env.company.name - for res_id in result_email.keys(): - name = '%s%s%s' % (company_name, ' ' if doc_names.get(res_id) else '', doc_names.get(res_id, '')) - result[res_id] = tools.formataddr((name, result_email[res_id])) - - left_ids = set(_res_ids) - set(result_email) - if left_ids: - result.update(dict((res_id, default) for res_id in left_ids)) - - return result - @api.model def _notify_get_reply_to_on_records(self, default=None, records=None, company=None, doc_names=None): - """ Generic wrapper on ``_notify_get_reply_to`` checking mail.thread inheritance - and allowing to call model-specific implementation in a one liner. This - method should not be overridden. """ - if records and hasattr(records, '_notify_get_reply_to'): - return records._notify_get_reply_to(default=default, company=company, doc_names=doc_names) - return self._notify_get_reply_to(default=default, records=records, company=company, doc_names=doc_names) + """ Moved to ``BaseModel._notify_get_reply_to()`` """ + records = records if records else self + return records._notify_get_reply_to(default=default, company=company, doc_names=doc_names) def _notify_email_recipient_values(self, recipient_ids): """ Format email notification recipient values to store on the notification diff --git a/addons/mail/models/models.py b/addons/mail/models/models.py index 1159a7ff6fd..1008fe0c4bf 100644 --- a/addons/mail/models/models.py +++ b/addons/mail/models/models.py @@ -3,15 +3,181 @@ from lxml.builder import E -from odoo import models, api +from odoo import api, models, tools, _ class BaseModel(models.AbstractModel): _inherit = 'base' # ------------------------------------------------------------ + # GENERIC MAIL FEATURES + # ------------------------------------------------------------ + + def _mail_track(self, tracked_fields, initial): + """ For a given record, fields to check (tuple column name, column info) + and initial values, return a valid command to create tracking values. + + :param tracked_fields: fields_get of updated fields on which tracking + is checked and performed; + :param initial: dict of initial values for each updated fields; + + :return: a tuple (changes, tracking_value_ids) where + changes: set of updated column names; + tracking_value_ids: a list of ORM (0, 0, values) commands to create + ``mail.tracking.value`` records; + + Override this method on a specific model to implement model-specific + behavior. Also consider inheriting from ``mail.thread``. """ + self.ensure_one() + changes = set() # contains onchange tracked fields that changed + tracking_value_ids = [] + + # generate tracked_values data structure: {'col_name': {col_info, new_value, old_value}} + for col_name, col_info in tracked_fields.items(): + if col_name not in initial: + continue + initial_value = initial[col_name] + new_value = self[col_name] + + if new_value != initial_value and (new_value or initial_value): # because browse null != False + tracking_sequence = getattr(self._fields[col_name], 'tracking', + getattr(self._fields[col_name], 'track_sequence', 100)) # backward compatibility with old parameter name + if tracking_sequence is True: + tracking_sequence = 100 + tracking = self.env['mail.tracking.value'].create_tracking_values(initial_value, new_value, col_name, col_info, tracking_sequence, self._name) + if tracking: + tracking_value_ids.append([0, 0, tracking]) + changes.add(col_name) + + return changes, tracking_value_ids + + def _message_get_default_recipients(self): + """ Generic implementation for finding default recipient to mail on + a recordset. This method is a generic implementation available for + all models as we could send an email through mail templates on models + not inheriting from mail.thread. + + Override this method on a specific model to implement model-specific + behavior. Also consider inheriting from ``mail.thread``. """ + res = {} + for record in self: + recipient_ids, email_to, email_cc = [], False, False + if 'partner_id' in record and record.partner_id: + recipient_ids.append(record.partner_id.id) + elif 'email_normalized' in record and record.email_normalized: + email_to = record.email_normalized + elif 'email_from' in record and record.email_from: + email_to = record.email_from + elif 'partner_email' in record and record.partner_email: + email_to = record.partner_email + elif 'email' in record and record.email: + email_to = record.email + res[record.id] = {'partner_ids': recipient_ids, 'email_to': email_to, 'email_cc': email_cc} + return res + + def _notify_get_reply_to(self, default=None, records=None, company=None, doc_names=None): + """ Returns the preferred reply-to email address when replying to a thread + on documents. This method is a generic implementation available for + all models as we could send an email through mail templates on models + not inheriting from mail.thread. + + Reply-to is formatted like "MyCompany MyDocument <reply.to@domain>". + Heuristic it the following: + * search for specific aliases as they always have priority; it is limited + to aliases linked to documents (like project alias for task for example); + * use catchall address; + * use default; + + This method can be used as a generic tools if self is a void recordset. + + Override this method on a specific model to implement model-specific + behavior. Also consider inheriting from ``mail.thread``. + An example would be tasks taking their reply-to alias from their project. + + :param default: default email if no alias or catchall is found; + :param records: DEPRECATED, self should be a valid record set or an + empty recordset if a generic reply-to is required; + :param company: used to compute company name part of the from name; provide + it if already known, otherwise fall back on user company; + :param doc_names: dict(res_id, doc_name) used to compute doc name part of + the from name; provide it if already known to avoid queries, otherwise + name_get on document will be performed; + :return result: dictionary. Keys are record IDs and value is formatted + like an email "Company_name Document_name <reply_to@email>"/ + """ + if records: + raise ValueError('Use of records is deprecated as this method is available on BaseModel.') + + _records = self + model = _records._name if _records and _records._name != 'mail.thread' else False + res_ids = _records.ids if _records and model else [] + _res_ids = res_ids or [False] # always have a default value located in False + + alias_domain = self.env['ir.config_parameter'].sudo().get_param("mail.catchall.domain") + result = dict.fromkeys(_res_ids, False) + result_email = dict() + doc_names = doc_names if doc_names else dict() + + if alias_domain: + if model and res_ids: + if not doc_names: + doc_names = dict((rec.id, rec.display_name) for rec in _records) + + mail_aliases = self.env['mail.alias'].sudo().search([ + ('alias_parent_model_id.model', '=', model), + ('alias_parent_thread_id', 'in', res_ids), + ('alias_name', '!=', False)]) + # take only first found alias for each thread_id, to match order (1 found -> limit=1 for each res_id) + for alias in mail_aliases: + result_email.setdefault(alias.alias_parent_thread_id, '%s@%s' % (alias.alias_name, alias_domain)) + + # left ids: use catchall + left_ids = set(_res_ids) - set(result_email) + if left_ids: + catchall = self.env['ir.config_parameter'].sudo().get_param("mail.catchall.alias") + if catchall: + result_email.update(dict((rid, '%s@%s' % (catchall, alias_domain)) for rid in left_ids)) + + # compute name of reply-to - TDE tocheck: quotes and stuff like that + company_name = company.name if company else self.env.company.name + for res_id in result_email: + name = '%s%s%s' % (company_name, ' ' if doc_names.get(res_id) else '', doc_names.get(res_id, '')) + result[res_id] = tools.formataddr((name, result_email[res_id])) + + left_ids = set(_res_ids) - set(result_email) + if left_ids: + result.update(dict((res_id, default) for res_id in left_ids)) + + return result + + # ------------------------------------------------------------ + # ALIAS MANAGEMENT + # ------------------------------------------------------------ + + def _alias_check_contact(self, message, message_dict, alias): + """ Deprecated, remove in v14+ """ + error_msg = self._alias_get_error_message(message, message_dict, alias) + return error_msg if error_msg else True + + def _alias_get_error_message(self, message, message_dict, alias): + """ Generic method that takes a record not necessarily inheriting from + mail.alias.mixin. """ + author = self.env['res.partner'].browse(message_dict.get('author_id', False)) + if alias.alias_contact == 'followers': + if not self.ids: + return _('incorrectly configured alias (unknown reference record)') + if not hasattr(self, "message_partner_ids") or not hasattr(self, "message_channel_ids"): + return _('incorrectly configured alias') + accepted_partner_ids = self.message_partner_ids | self.message_channel_ids.mapped('channel_partner_ids') + if not author or author not in accepted_partner_ids: + return _('restricted to followers') + elif alias.alias_contact == 'partners' and not author: + return _('restricted to known authors') + return False + + # ------------------------------------------------------------ # ACTIVITY - # ----------------------------------------------------------- + # ------------------------------------------------------------ @api.model def _get_default_activity_view(self): diff --git a/addons/mail/wizard/mail_compose_message.py b/addons/mail/wizard/mail_compose_message.py index f66bdba6557..e9df4a0cb80 100644 --- a/addons/mail/wizard/mail_compose_message.py +++ b/addons/mail/wizard/mail_compose_message.py @@ -278,7 +278,7 @@ class MailComposer(models.TransientModel): reply_to_value = dict.fromkeys(res_ids, None) if mass_mail_mode and not self.no_auto_thread: records = self.env[self.model].browse(res_ids) - reply_to_value = self.env['mail.thread']._notify_get_reply_to_on_records(default=self.email_from, records=records) + reply_to_value = records._notify_get_reply_to(default=self.email_from) blacklisted_rec_ids = [] if mass_mail_mode and issubclass(type(self.env[self.model]), self.pool['mail.thread.blacklist']): @@ -462,7 +462,7 @@ class MailComposer(models.TransientModel): default_recipients = {} if not self.partner_ids: records = self.env[self.model].browse(res_ids).sudo() - default_recipients = self.env['mail.thread']._message_get_default_recipients_on_records(records) + default_recipients = records._message_get_default_recipients() results = dict.fromkeys(res_ids, False) for res_id in res_ids: |
