changeset 26357bb18e09 in modules/party:default
details: https://hg.tryton.org/modules/party?cmd=changeset&node=26357bb18e09
description:
        Move distance definition into party module

        issue10104
        review343621004
diffstat:

 CHANGELOG            |   1 +
 contact_mechanism.py |   3 +-
 party.py             |  54 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 tests/test_party.py  |  21 ++++++++++++++++++++
 4 files changed, 77 insertions(+), 2 deletions(-)

diffs (137 lines):

diff -r 508fd56d0ae5 -r 26357bb18e09 CHANGELOG
--- a/CHANGELOG Sun Mar 21 16:09:13 2021 +0100
+++ b/CHANGELOG Wed Mar 24 21:37:48 2021 +0100
@@ -1,3 +1,4 @@
+* Add simple distance between parties
 * Configure available identifiers
 * Add ar, at, by, cn, cr, gr, id, il, kr, lt, no, ro and se identifiers
 
diff -r 508fd56d0ae5 -r 26357bb18e09 contact_mechanism.py
--- a/contact_mechanism.py      Sun Mar 21 16:09:13 2021 +0100
+++ b/contact_mechanism.py      Wed Mar 24 21:37:48 2021 +0100
@@ -86,7 +86,8 @@
     @classmethod
     def __setup__(cls):
         super(ContactMechanism, cls).__setup__()
-        cls._order.insert(0, ('party', 'ASC'))
+        cls._order.insert(0, ('party.distance', 'ASC NULLS LAST'))
+        cls._order.insert(1, ('party', 'ASC'))
 
     @staticmethod
     def default_type():
diff -r 508fd56d0ae5 -r 26357bb18e09 party.py
--- a/party.py  Sun Mar 21 16:09:13 2021 +0100
+++ b/party.py  Wed Mar 24 21:37:48 2021 +0100
@@ -3,6 +3,7 @@
 from stdnum import get_cc_module
 import stdnum.exceptions
 from sql import Null, Column, Literal
+from sql.aggregate import Min
 from sql.functions import CharLength, Substring, Position
 
 from trytond.i18n import gettext
@@ -63,6 +64,7 @@
     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')
+    distance = fields.Function(fields.Integer('Distance'), 'get_distance')
 
     @classmethod
     def __setup__(cls):
@@ -71,7 +73,8 @@
         cls._sql_constraints = [
             ('code_uniq', Unique(t, t.code), 'party.msg_party_code_unique')
             ]
-        cls._order.insert(0, ('name', 'ASC'))
+        cls._order.insert(0, ('distance', 'ASC NULLS LAST'))
+        cls._order.insert(1, ('name', 'ASC'))
         cls.active.states.update({
                 'readonly': Bool(Eval('replaced_by')),
                 })
@@ -170,6 +173,55 @@
         return ''
 
     @classmethod
+    def _distance_query(cls, usages=None, party=None, depth=None):
+        context = Transaction().context
+        if party is None:
+            party = context.get('related_party')
+
+        if not party:
+            return
+
+        table = cls.__table__()
+        return table.select(
+            table.id.as_('to'),
+            Literal(0).as_('distance'),
+            where=(table.id == party))
+
+    @classmethod
+    def get_distance(cls, parties, name):
+        distances = {p.id: None for p in parties}
+        query = cls._distance_query()
+        if query:
+            cursor = Transaction().connection.cursor()
+            cursor.execute(*query.select(
+                    query.to.as_('to'),
+                    Min(query.distance).as_('distance'),
+                    group_by=[query.to]))
+            distances.update(cursor)
+        return distances
+
+    @classmethod
+    def order_distance(cls, tables):
+        party, _ = tables[None]
+        key = 'distance'
+        if key not in tables:
+            query = cls._distance_query()
+            if not query:
+                return []
+            query = query.select(
+                    query.to.as_('to'),
+                    Min(query.distance).as_('distance'),
+                    group_by=[query.to])
+            join = party.join(query, type_='LEFT',
+                condition=query.to == party.id)
+            tables[key] = {
+                None: (join.right, join.condition),
+                }
+        else:
+            query, _ = tables[key][None]
+        return [query.distance]
+
+    @classmethod
     def _new_code(cls, **pattern):
         pool = Pool()
         Configuration = pool.get('party.configuration')
diff -r 508fd56d0ae5 -r 26357bb18e09 tests/test_party.py
--- a/tests/test_party.py       Sun Mar 21 16:09:13 2021 +0100
+++ b/tests/test_party.py       Wed Mar 24 21:37:48 2021 +0100
@@ -449,6 +449,27 @@
             set(Party.tax_identifier_types())
             - set(dict(IDENTIFIER_TYPES).keys()))
 
+    @with_transaction()
+    def test_party_distance(self):
+        "Test party distance"
+        pool = Pool()
+        Party = pool.get('party.party')
+
+        A, B, = Party.create([{
+                    'name': 'A',
+                    }, {
+                    'name': 'B',
+                    }])
+
+        parties = Party.search([])
+        self.assertEqual([p.distance for p in parties], [None] * 2)
+
+        with Transaction().set_context(related_party=A.id):
+            parties = Party.search([])
+            self.assertEqual(
+                [(p.name, p.distance) for p in parties],
+                [('A', 0), ('B', None)])
+
 
 def suite():
     suite = trytond.tests.test_tryton.suite()

Reply via email to