[FIX] partner_phone_country_validation: correct overall fragile process

This commit is contained in:
Stéphan Sainléger
2026-03-06 10:24:51 +01:00
parent 0d7a57d321
commit 946b69e722
2 changed files with 39 additions and 58 deletions

View File

@@ -1,73 +1,54 @@
from odoo import api, models, _ from odoo import api, models, _
from odoo.addons.partner_phone_country_validation.tools.get_country_from_phone_number import get_country_from_phone_number from odoo.addons.partner_phone_country_validation.tools.get_country_from_phone_number import (
get_country_from_phone_number,
)
from odoo.exceptions import ValidationError from odoo.exceptions import ValidationError
import logging
_logger = logging.getLogger(__name__)
class Partner(models.Model): class Partner(models.Model):
_name = 'res.partner' _name = "res.partner"
_inherit = ['res.partner', 'phone.validation.mixin'] _inherit = ["res.partner", "phone.validation.mixin"]
@api.constrains('country_id','phone','mobile') @api.constrains("country_id", "phone", "mobile")
def _check_country_id(self): def _check_country_id(self):
if not self.country_id and (self.phone or self.mobile): for partner in self:
raise ValidationError(_('You must set a country for the phone number')) if not partner.country_id and (partner.phone or partner.mobile):
raise ValidationError(_("You must set a country for the phone number"))
@api.onchange('country_id')
def _onchange_country(self):
self.format_mobile_from_country()
self.format_phone_from_country()
def format_number_zerozero(self, number): def _normalize_phone_number(self, number):
if number.startswith("00"): """Convert 00xx format to +xx international format."""
number = "+"+number[2:] if number and number.startswith("00"):
return "+" + number[2:]
return number return number
def format_phone_from_country(self): def _set_country_from_phone_number(self, phone_number):
if self.phone: """Auto-detect and set country from phone number prefix if not already set."""
country = None if not phone_number or self.country_id:
if self.phone.startswith('+'): return
country = self.env['res.country'].search( country_code = get_country_from_phone_number(phone_number)
[('code', '=', get_country_from_phone_number(self.phone))], limit=1 if country_code:
) country = self.env["res.country"].search(
if self.country_id: [("code", "=", country_code)], limit=1
country = self.country_id )
if country: if country:
self.phone = self.phone_format(self.phone, country=country) self.country_id = country
def format_mobile_from_country(self): @api.onchange("phone", "country_id", "company_id")
if self.mobile:
country = None
if self.mobile.startswith('+'):
country = self.env['res.country'].search(
[('code', '=', get_country_from_phone_number(self.mobile))], limit=1
)
if self.country_id:
country = self.country_id
if country:
self.mobile = self.phone_format(self.mobile, country=country)
def set_country_from_phone_number(self, phone_number):
country = self.env['res.country'].search(
[('code', '=', get_country_from_phone_number(phone_number))], limit=1
)
if country and not self.country_id:
self.country_id = country
@api.onchange('phone')
def _onchange_phone_validation(self): def _onchange_phone_validation(self):
# If no country is found, we define the country based on the beginning of the number # Normalize 00xx → +xx before standard processing
if self.phone: if self.phone:
self.phone = self.format_number_zerozero(self.phone) self.phone = self._normalize_phone_number(self.phone)
self.set_country_from_phone_number(self.phone) # Auto-detect country if not set
self.format_phone_from_country() self._set_country_from_phone_number(self.phone)
# Let standard module do the formatting
super()._onchange_phone_validation()
@api.onchange('mobile') @api.onchange("mobile", "country_id", "company_id")
def _onchange_mobile_validation(self): def _onchange_mobile_validation(self):
# If no country is found, we define the country based on the beginning of the number # Normalize 00xx → +xx before standard processing
if self.mobile: if self.mobile:
self.mobile = self.format_number_zerozero(self.mobile) self.mobile = self._normalize_phone_number(self.mobile)
self.set_country_from_phone_number(self.mobile) # Auto-detect country if not set
self.format_mobile_from_country() self._set_country_from_phone_number(self.mobile)
# Let standard module do the formatting
super()._onchange_mobile_validation()

View File

@@ -7,7 +7,7 @@ try:
def get_country_from_phone_number(number): def get_country_from_phone_number(number):
try: try:
number = phonenumbers.parse(number) number = phonenumbers.parse(number)
return phonenumbers.region_code_for_number(number) return phonenumbers.region_code_for_number(number)
except phonenumbers.phonenumberutil.NumberParseException: except phonenumbers.phonenumberutil.NumberParseException:
return False return False
@@ -22,4 +22,4 @@ except ImportError:
"verified. Please install the `phonenumbers` Python module." "verified. Please install the `phonenumbers` Python module."
) )
_phonenumbers_lib_warning = True _phonenumbers_lib_warning = True
return number return number