From bdfb802293d9a3eebb378a15ed65f48b7c3182b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Wed, 13 Dec 2023 09:39:25 +0100 Subject: [PATCH] [IMP] phone_validation: try to be defensive when parsing phone numbers After some testing notably with WhatsApp module, it appears usage of phone numbers could be a bit more defensive to try to accomodate with data users entered. Notably when failing to recognize a number, we can distinguish error and try to reformat it based on two commonly spotted errors * missing "+" in front of a E164-like number (e.g. '32455001122'); * usage of "00" in countries where it is not really standard to use it instead of a "+" (e.g. '0032455001122'); Those find of numbers generate a 'TOO_LONG' error from phonenumbers library. In that case we try to reformat it just to see if we can do better with it. Task-3608129 (Whatsapp: Moultifix !) X-original-commit: odoo/odoo@85c1306156fdf3d51b0914895a42e566d586caf7 Part-of: odoo/odoo#146398 --- .../i18n/phone_validation.pot | 23 ++++++++++++++++ .../tools/phone_validation.py | 26 ++++++++++++++++++- 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/addons/phone_validation/i18n/phone_validation.pot b/addons/phone_validation/i18n/phone_validation.pot index 79cdfa53314..adbf693decf 100644 --- a/addons/phone_validation/i18n/phone_validation.pot +++ b/addons/phone_validation/i18n/phone_validation.pot @@ -185,6 +185,20 @@ msgid "" " mass mailing sms anymore, from any list" msgstr "" +#. module: phone_validation +#. odoo-python +#: code:addons/phone_validation/tools/phone_validation.py:0 +#, python-format +msgid "Impossible number %s: not a valid country prefix." +msgstr "" + +#. module: phone_validation +#. odoo-python +#: code:addons/phone_validation/tools/phone_validation.py:0 +#, python-format +msgid "Impossible number %s: not enough digits." +msgstr "" + #. module: phone_validation #. odoo-python #: code:addons/phone_validation/tools/phone_validation.py:0 @@ -192,6 +206,15 @@ msgstr "" msgid "Impossible number %s: probably invalid number of digits." msgstr "" +#. module: phone_validation +#. odoo-python +#: code:addons/phone_validation/tools/phone_validation.py:0 +#: code:addons/phone_validation/tools/phone_validation.py:0 +#: code:addons/phone_validation/tools/phone_validation.py:0 +#, python-format +msgid "Impossible number %s: too many digits." +msgstr "" + #. module: phone_validation #: model:ir.model.fields,help:phone_validation.field_mail_thread_phone__mobile_blacklisted msgid "" diff --git a/addons/phone_validation/tools/phone_validation.py b/addons/phone_validation/tools/phone_validation.py index 918332de8d3..a6465af0613 100644 --- a/addons/phone_validation/tools/phone_validation.py +++ b/addons/phone_validation/tools/phone_validation.py @@ -22,7 +22,31 @@ try: ) from e if not phonenumbers.is_possible_number(phone_nbr): - raise UserError(_('Impossible number %s: probably invalid number of digits.', number)) + reason = phonenumbers.is_possible_number_with_reason(phone_nbr) + if reason == phonenumbers.ValidationResult.INVALID_COUNTRY_CODE: + raise UserError(_('Impossible number %s: not a valid country prefix.', number)) + if reason == phonenumbers.ValidationResult.TOO_SHORT: + raise UserError(_('Impossible number %s: not enough digits.', number)) + # in case of "TOO_LONG", we may try to reformat the number in case it was + # entered without '+' prefix or using leading '++' not always recognized; + # in any case final error should keep the original number to ease tracking + if reason == phonenumbers.ValidationResult.TOO_LONG: + # people may enter 0033... instead of +33... + if number.startswith('00'): + try: + phone_nbr = phone_parse(f'+{number.lstrip("00")}', country_code) + except UserError: + raise UserError(_('Impossible number %s: too many digits.', number)) + # people may enter 33... instead of +33... + elif not number.startswith('+'): + try: + phone_nbr = phone_parse(f'+{number}', country_code) + except UserError: + raise UserError(_('Impossible number %s: too many digits.', number)) + else: + raise UserError(_('Impossible number %s: too many digits.', number)) + else: + 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))