changeset e75508d267ca in modules/party:default
details: https://hg.tryton.org/modules/party?cmd=changeset&node=e75508d267ca
description:
Allow setting a single contact mechanism at party creation
issue10811
review354111002
diffstat:
CHANGELOG | 1 +
message.xml | 3 ++
party.py | 58 +++++++++++++++++++++++++++++++++++++++++++++++-----
tests/test_party.py | 25 ++++++++++++++++++++++
4 files changed, 81 insertions(+), 6 deletions(-)
diffs (172 lines):
diff -r 34cd2ac1a5b8 -r e75508d267ca CHANGELOG
--- a/CHANGELOG Fri Oct 08 19:34:33 2021 +0200
+++ b/CHANGELOG Sun Oct 10 22:18:57 2021 +0200
@@ -1,3 +1,4 @@
+* Allow setting a single contact mechanism at party creation
* Make identifiers deactivatable
* Replace party on identifier when replacing parties
* Add au_abn and au_acn as tax identifiers
diff -r 34cd2ac1a5b8 -r e75508d267ca message.xml
--- a/message.xml Fri Oct 08 19:34:33 2021 +0200
+++ b/message.xml Sun Oct 10 22:18:57 2021 +0200
@@ -6,6 +6,9 @@
<record model="ir.message" id="msg_party_code_unique">
<field name="text">The code on party must be unique.</field>
</record>
+ <record model="ir.message" id="msg_party_set_contact_mechanism">
+ <field name="text">To change the "%(field)s" for party
"%(party)s", you must edit their contact mechanisms.</field>
+ </record>
<record model="ir.message" id="msg_contact_mechanism_change_party">
<field name="text">You cannot change the party of contact
mechanism "%(contact)s".</field>
</record>
diff -r 34cd2ac1a5b8 -r e75508d267ca party.py
--- a/party.py Fri Oct 08 19:34:33 2021 +0200
+++ b/party.py Sun Oct 10 22:18:57 2021 +0200
@@ -9,6 +9,7 @@
from trytond.i18n import gettext
from trytond.model import (ModelView, ModelSQL, MultiValueMixin, ValueMixin,
DeactivableMixin, fields, Unique, sequence_ordered)
+from trytond.model.exceptions import AccessError
from trytond.wizard import Wizard, StateTransition, StateView, Button
from trytond.pyson import Eval, Bool
from trytond.transaction import Transaction
@@ -19,11 +20,17 @@
from .exceptions import (
InvalidIdentifierCode, VIESUnavailable, SimilarityWarning, EraseError)
+from .contact_mechanism import _PHONE_TYPES
+
class Party(DeactivableMixin, ModelSQL, ModelView, MultiValueMixin):
"Party"
__name__ = 'party.party'
+ _contact_mechanism_states = {
+ 'readonly': Eval('id', -1) >= 0,
+ }
+
name = fields.Char(
"Name", select=True,
help="The main identifier of the party.")
@@ -59,13 +66,25 @@
},
help="The party replacing this one.")
full_name = fields.Function(fields.Char('Full Name'), 'get_full_name')
- phone = fields.Function(fields.Char('Phone'), 'get_mechanism')
- mobile = fields.Function(fields.Char('Mobile'), 'get_mechanism')
- fax = fields.Function(fields.Char('Fax'), 'get_mechanism')
- email = fields.Function(fields.Char('E-Mail'), 'get_mechanism')
- website = fields.Function(fields.Char('Website'), 'get_mechanism')
+ phone = fields.Function(
+ fields.Char("Phone", states=_contact_mechanism_states),
+ 'get_contact_mechanism', setter='set_contact_mechanism')
+ mobile = fields.Function(
+ fields.Char("Mobile", states=_contact_mechanism_states),
+ 'get_contact_mechanism', setter='set_contact_mechanism')
+ fax = fields.Function(
+ fields.Char("Fax", states=_contact_mechanism_states),
+ 'get_contact_mechanism', setter='set_contact_mechanism')
+ email = fields.Function(
+ fields.Char("E-Mail", states=_contact_mechanism_states),
+ 'get_contact_mechanism', setter='set_contact_mechanism')
+ website = fields.Function(
+ fields.Char("Website", states=_contact_mechanism_states),
+ 'get_contact_mechanism', setter='set_contact_mechanism')
distance = fields.Function(fields.Integer('Distance'), 'get_distance')
+ del _contact_mechanism_states
+
@classmethod
def __setup__(cls):
super(Party, cls).__setup__()
@@ -155,13 +174,32 @@
def get_full_name(self, name):
return self.name
- def get_mechanism(self, name):
+ def get_contact_mechanism(self, name):
for mechanism in self.contact_mechanisms:
if mechanism.type == name:
return mechanism.value
return ''
@classmethod
+ def set_contact_mechanism(cls, parties, name, value):
+ pool = Pool()
+ ContactMechanism = pool.get('party.contact_mechanism')
+ contact_mechanisms = []
+ for party in parties:
+ if getattr(party, name):
+ type_string = cls.fields_get([name])[name]['string']
+ raise AccessError(gettext(
+ 'party.msg_party_set_contact_mechanism',
+ party=party.rec_name,
+ field=type_string))
+ if value:
+ contact_mechanisms.append(ContactMechanism(
+ party=party,
+ type=name,
+ value=value))
+ ContactMechanism.save(contact_mechanisms)
+
+ @classmethod
def _distance_query(cls, usages=None, party=None, depth=None):
context = Transaction().context
if party is None:
@@ -211,6 +249,14 @@
return [query.distance]
@classmethod
+ def index_set_field(cls, name):
+ index = super().index_set_field(name)
+ if name in _PHONE_TYPES:
+ # Phone validation may need the address country
+ index = cls.index_set_field('addresses') + 1
+ return index
+
+ @classmethod
def _new_code(cls, **pattern):
pool = Pool()
Configuration = pool.get('party.configuration')
diff -r 34cd2ac1a5b8 -r e75508d267ca tests/test_party.py
--- a/tests/test_party.py Fri Oct 08 19:34:33 2021 +0200
+++ b/tests/test_party.py Sun Oct 10 22:18:57 2021 +0200
@@ -13,6 +13,7 @@
from trytond.tests.test_tryton import doctest_checker
from trytond.pool import Pool
from trytond.exceptions import UserError
+from trytond.model.exceptions import AccessError
from trytond.transaction import Transaction
from ..party import IDENTIFIER_TYPES
@@ -300,6 +301,30 @@
mechanism = create('email', '[email protected]')
@with_transaction()
+ def test_set_contact_mechanism(self):
+ "Test set_contact_mechanism"
+ pool = Pool()
+ Party = pool.get('party.party')
+
+ party = Party(email='[email protected]')
+ party.save()
+
+ self.assertEqual(party.email, '[email protected]')
+
+ @with_transaction()
+ def test_set_contact_mechanism_with_value(self):
+ "Test set_contact_mechanism"
+ pool = Pool()
+ Party = pool.get('party.party')
+
+ party = Party(email='[email protected]')
+ party.save()
+
+ party.email = '[email protected]'
+ with self.assertRaises(AccessError):
+ party.save()
+
+ @with_transaction()
def test_contact_mechanism_get_no_usage(self):
"Test contact_mechanism_get with no usage"
pool = Pool()