details: https://code.tryton.org/tryton/commit/55a07a868730
branch: default
user: Cédric Krier <[email protected]>
date: Thu Apr 23 09:18:59 2026 +0200
description:
Guess the type of contact mechanism
Closes #14768
diffstat:
modules/party/CHANGELOG | 1 +
modules/party/contact_mechanism.py | 36
+++++++++-
modules/party/tests/scenario_party_contact_mechanism_notifications.rst | 2 +-
modules/party/view/contact_mechanism_form.xml | 4 +-
modules/party/view/contact_mechanism_tree.xml | 2 +-
modules/party/view/contact_mechanism_tree_sequence.xml | 2 +-
6 files changed, 41 insertions(+), 6 deletions(-)
diffs (134 lines):
diff -r 4b7edc0b4b00 -r 55a07a868730 modules/party/CHANGELOG
--- a/modules/party/CHANGELOG Thu Apr 23 09:19:13 2026 +0200
+++ b/modules/party/CHANGELOG Thu Apr 23 09:18:59 2026 +0200
@@ -1,3 +1,4 @@
+* Guess the type of contact mechanism
Version 8.0.0 - 2026-04-20
--------------------------
diff -r 4b7edc0b4b00 -r 55a07a868730 modules/party/contact_mechanism.py
--- a/modules/party/contact_mechanism.py Thu Apr 23 09:19:13 2026 +0200
+++ b/modules/party/contact_mechanism.py Thu Apr 23 09:18:59 2026 +0200
@@ -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 @@
'fax',
}
+_URL_REGEX = re.compile(r'^(http|ftp)s?://', re.IGNORECASE)
+
class _ContactMechanismMixin:
__slots__ = ()
@@ -140,7 +144,7 @@
@staticmethod
def default_type():
- return 'phone'
+ return 'other'
@classmethod
def default_party(cls):
@@ -219,9 +223,39 @@
# 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_)
diff -r 4b7edc0b4b00 -r 55a07a868730
modules/party/tests/scenario_party_contact_mechanism_notifications.rst
--- a/modules/party/tests/scenario_party_contact_mechanism_notifications.rst
Thu Apr 23 09:19:13 2026 +0200
+++ b/modules/party/tests/scenario_party_contact_mechanism_notifications.rst
Thu Apr 23 09:18:59 2026 +0200
@@ -42,7 +42,7 @@
Change contact mechanism type::
- >>> contact_mechanism.type = 'other'
+ >>> contact_mechanism.type = 'jabber'
>>> contact_mechanism.value = "[email protected]"
Check notifications::
diff -r 4b7edc0b4b00 -r 55a07a868730
modules/party/view/contact_mechanism_form.xml
--- a/modules/party/view/contact_mechanism_form.xml Thu Apr 23 09:19:13
2026 +0200
+++ b/modules/party/view/contact_mechanism_form.xml Thu Apr 23 09:18:59
2026 +0200
@@ -12,8 +12,6 @@
<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 @@
<label name="sip"/>
<field name="sip" widget="sip"/>
</group>
+ <label name="type"/>
+ <field name="type"/>
<label name="name"/>
<field name="name"/>
<label name="language"/>
diff -r 4b7edc0b4b00 -r 55a07a868730
modules/party/view/contact_mechanism_tree.xml
--- a/modules/party/view/contact_mechanism_tree.xml Thu Apr 23 09:19:13
2026 +0200
+++ b/modules/party/view/contact_mechanism_tree.xml Thu Apr 23 09:18:59
2026 +0200
@@ -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"/>
diff -r 4b7edc0b4b00 -r 55a07a868730
modules/party/view/contact_mechanism_tree_sequence.xml
--- a/modules/party/view/contact_mechanism_tree_sequence.xml Thu Apr 23
09:19:13 2026 +0200
+++ b/modules/party/view/contact_mechanism_tree_sequence.xml Thu Apr 23
09:18:59 2026 +0200
@@ -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"/>