Guess the type of contact mechanism

Closes #14768
This commit is contained in:
Cédric Krier
2026-04-23 09:18:59 +02:00
parent 48d5d5d996
commit b83d7055a9
6 changed files with 41 additions and 6 deletions
+1
View File
@@ -1,3 +1,4 @@
* Guess the type of contact mechanism
Version 8.0.0 - 2026-04-20
--------------------------
+35 -1
View File
@@ -1,5 +1,7 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
import re
from itertools import chain
try:
@@ -39,6 +41,8 @@ _PHONE_TYPES = {
'fax',
}
_URL_REGEX = re.compile(r'^(http|ftp)s?://', re.IGNORECASE)
class _ContactMechanismMixin:
__slots__ = ()
@@ -140,7 +144,7 @@ class ContactMechanism(
@staticmethod
def default_type():
return 'phone'
return 'other'
@classmethod
def default_party(cls):
@@ -219,9 +223,39 @@ class ContactMechanism(
# Setting value is done by on_changes
pass
def _guess_types(self, value, type_):
types = []
if type_ in {'skype', 'sip', 'irc', 'jabber'}:
return types
if phonenumbers:
if phonenumber := self._parse_phonenumber(value):
phonenumber_type = phonenumbers.number_type(phonenumber)
if phonenumber_type in {
phonenumbers.PhoneNumberType.FIXED_LINE}:
types.append('phone')
elif phonenumber_type in {
phonenumbers.PhoneNumberType.MOBILE}:
types.append('mobile')
else:
types.extend(_PHONE_TYPES)
try:
validate_email(value, check_deliverability=False)
except EmailNotValidError:
pass
else:
types.append('email')
if re.match(_URL_REGEX, value):
types.append('website')
return types
@fields.depends(
methods=['on_change_with_url', 'format_value', 'format_value_compact'])
def _change_value(self, value, type_):
if value:
guess_types = self._guess_types(value, type_)
if guess_types and type_ not in guess_types:
self.type = type_ = guess_types[0]
self.value = self.format_value(value=value, type_=type_)
self.value_compact = self.format_value_compact(
value=value, type_=type_)
@@ -42,7 +42,7 @@ Check notifications::
Change contact mechanism type::
>>> contact_mechanism.type = 'other'
>>> contact_mechanism.type = 'jabber'
>>> contact_mechanism.value = "test@example.com"
Check notifications::
@@ -12,8 +12,6 @@ this repository contains the full copyright notices and license terms. -->
<label name="sequence"/>
<field name="sequence"/>
</group>
<label name="type"/>
<field name="type"/>
<group col="2" colspan="2" id="value">
<label name="other_value"/>
<field name="other_value"/>
@@ -26,6 +24,8 @@ this repository contains the full copyright notices and license terms. -->
<label name="sip"/>
<field name="sip" widget="sip"/>
</group>
<label name="type"/>
<field name="type"/>
<label name="name"/>
<field name="name"/>
<label name="language"/>
@@ -2,7 +2,7 @@
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<tree>
<field name="type"/>
<field name="type" optional="0"/>
<field name="value" expand="1"/>
<field name="name" expand="1" optional="0"/>
<field name="party" expand="2" optional="0"/>
@@ -2,7 +2,7 @@
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<tree sequence="sequence" editable="1">
<field name="type"/>
<field name="type" optional="0"/>
<field name="value" expand="1"/>
<field name="name" expand="1" optional="0"/>
<field name="party" expand="2" optional="0"/>