Skip to content
Snippets Groups Projects
Commit 96a00471 authored by Fabien Pinckaers's avatar Fabien Pinckaers Committed by Thibault Delavallée
Browse files

[ADD] phone_validation: tool module allowing phone number validation

Using phonenumbers library this module adds tools methods as well as a
small mixin for models that want to activate phone number validation
and formatting.

Formatting can be done always using an international format or having
both national and international format. This is configured on the
company.

Note that phonenumbers library is optional. Installing this module without
having the lib installed just skip its use but should not crash.
parent 26b851e5
No related branches found
No related tags found
No related merge requests found
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import tools
from . import models
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
{
'name': 'Phone Numbers Validation',
'summary': 'Validate and format phone numbers',
'sequence': '9999',
'category': 'Hidden',
'description': """
Phone Numbers Validation
========================
This module adds the feature of validation and formatting phone numbers
according to a destination country. It also handles national and international
formatting.
This module applies this feature to Leads and Contacts.""",
'data': [
],
'depends': ['base'],
}
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import res_company
from . import phone_validation_mixin
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import models
from odoo.addons.phone_validation.tools import phone_validation
class PhoneValidationMixin(models.AbstractModel):
_name = 'phone.validation.mixin'
def _phone_get_country_code(self):
if 'country_id' in self:
return self.country_id.code
return self.env.user.company_id.country_id.code
def _phone_get_always_international(self):
if 'company_id' in self:
return self.company_id.phone_international_format
return self.env.user.company_id.phone_international_format
def phone_format(self, number, country=None, company=None):
country_code = country.code if country else self._phone_get_country_code()
always_international = company.phone_international_format if company else self._phone_get_always_international()
return phone_validation.phone_format(
number, country_code if country_code else None,
always_international=always_international,
raise_exception=True
)
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import fields, models
class ResCompany(models.Model):
_inherit = 'res.company'
phone_international_format = fields.Boolean(
string="Enforce International Format", default=False,
help="Always encore phone numbers using international format. Otherwise"
"numbers coming from the company's country are nationaly formatted."
"International numbers are always using international format."
)
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import phone_validation
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import _
from odoo.exceptions import UserError
import logging
_logger = logging.getLogger(__name__)
_phonenumbers_lib_warning = False
try:
import phonenumbers
def phone_parse(number, country_code):
try:
phone_nbr = phonenumbers.parse(number, region=country_code, keep_raw_input=True)
except phonenumbers.phonenumberutil.NumberParseException as e:
raise UserError(_('Unable to parse %s:\n%s') % (number, e))
if not phonenumbers.is_possible_number(phone_nbr):
raise UserError(_('Impossible number %s: probably invalid number of digits') % number)
if not phonenumbers.is_valid_number(phone_nbr):
raise UserError(_('Invalid number %s: probably incorrect prefix') % number)
return phone_nbr
def phone_format(number, country_code, always_international=True, raise_exception=True):
try:
phone_nbr = phone_parse(number, country_code)
except (phonenumbers.phonenumberutil.NumberParseException, UserError) as e:
if raise_exception:
raise
else:
_logger.warning(_('Unable to format %s:\n%s') % number, e)
return number
if always_international and phone_nbr.country_code != country_code:
phone_fmt = phonenumbers.PhoneNumberFormat.INTERNATIONAL
else:
phone_fmt = phonenumbers.PhoneNumberFormat.NATIONAL
return phonenumbers.format_number(phone_nbr, phone_fmt)
except ImportError:
def phone_parse(number, country_code):
return False
def phone_format(number, country_code, always_international=True, raise_exception=True):
global _phonenumbers_lib_warning
if not _phonenumbers_lib_warning:
_logger.warning(
"The `phonenumbers` Python module is not installed, contact numbers will not be "
"verified. Try: pip install phonenumbers."
)
_phonenumbers_lib_warning = True
return number
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment