from odoo import models from odoo.addons.phone_validation.tools import phone_validation class BaseModel(models.AbstractModel): _inherit = 'base' def _sms_get_recipients_info(self, force_field=False, partner_fallback=True): """" Get SMS recipient information on current record set. This method checks for numbers and sanitation in order to centralize computation. Example of use cases * click on a field -> number is actually forced from field, find customer linked to record, force its number to field or fallback on customer fields; * contact -> find numbers from all possible phone fields on record, find customer, force its number to found field number or fallback on customer fields; :param force_field: either give a specific field to find phone number, either generic heuristic is used to find one based on ``_phone_get_number_fields``; :param partner_fallback: if no value found in the record, check its customer values based on ``_mail_get_partners``; :return dict: record.id: { 'partner': a res.partner recordset that is the customer (void or singleton) linked to the recipient. See ``_mail_get_partners``; 'sanitized': sanitized number to use (coming from record's field or partner's phone fields). Set to False is number impossible to parse and format; 'number': original number before sanitation; 'partner_store': whether the number comes from the customer phone fields. If False it means number comes from the record itself, even if linked to a customer; 'field_store': field in which the number has been found (generally mobile or phone, see ``_phone_get_number_fields``); } for each record in self """ result = dict.fromkeys(self.ids, False) tocheck_fields = [force_field] if force_field else self._phone_get_number_fields() for record in self: all_numbers = [record[fname] for fname in tocheck_fields if fname in record] all_partners = record._mail_get_partners()[record.id] valid_number, fname = False, False for fname in [f for f in tocheck_fields if f in record]: valid_number = record._phone_format(fname=fname) if valid_number: break if valid_number: result[record.id] = { 'partner': all_partners[0] if all_partners else self.env['res.partner'], 'sanitized': valid_number, 'number': record[fname], 'partner_store': False, 'field_store': fname, } elif all_partners and partner_fallback: partner = self.env['res.partner'] for partner in all_partners: for fname in self.env['res.partner']._phone_get_number_fields(): valid_number = partner._phone_format(fname=fname) if valid_number: break if not valid_number: fname = 'mobile' if partner.mobile else ('phone' if partner.phone else 'mobile') result[record.id] = { 'partner': partner, 'sanitized': valid_number if valid_number else False, 'number': partner[fname], 'partner_store': True, 'field_store': fname, } else: # did not find any sanitized number -> take first set value as fallback; # if none, just assign False to the first available number field value, fname = next( ((value, fname) for value, fname in zip(all_numbers, tocheck_fields) if value), (False, tocheck_fields[0] if tocheck_fields else False) ) result[record.id] = { 'partner': self.env['res.partner'], 'sanitized': False, 'number': value, 'partner_store': False, 'field_store': fname } return result