changeset f5c2c4885143 in modules/party_siret:default
details: 
https://hg.tryton.org/modules/party_siret?cmd=changeset&node=f5c2c4885143
description:
        Use party identifier to store SIREN and SIRET

        issue5834
        review397071002
diffstat:

 CHANGELOG                 |    1 +
 address.py                |  102 ++++++++++++++++++++++++++++++++++-----------
 address.xml               |    5 --
 exceptions.py             |   12 -----
 luhn.py                   |   18 --------
 message.xml               |   13 -----
 party.py                  |   47 ++++++++++++---------
 party.xml                 |    5 --
 tests/test_party_siret.py |   27 ------------
 tryton.cfg                |    1 -
 view/address_form.xml     |   13 -----
 view/party_form.xml       |   10 ----
 12 files changed, 104 insertions(+), 150 deletions(-)

diffs (353 lines):

diff -r e253d14b3240 -r f5c2c4885143 CHANGELOG
--- a/CHANGELOG Thu Feb 03 23:13:26 2022 +0100
+++ b/CHANGELOG Sun Feb 13 00:43:49 2022 +0100
@@ -1,3 +1,4 @@
+* Use party identifier to store SIREN and SIRET
 * Add support for Python 3.10
 * Remove support for Python 3.6
 
diff -r e253d14b3240 -r f5c2c4885143 address.py
--- a/address.py        Thu Feb 03 23:13:26 2022 +0100
+++ b/address.py        Sun Feb 13 00:43:49 2022 +0100
@@ -1,37 +1,87 @@
 # This file is part of Tryton.  The COPYRIGHT file at the top level of
 # this repository contains the full copyright notices and license terms.
-from trytond.i18n import gettext
+from sql import Literal, Null
+from sql.operators import Concat
+
 from trytond.model import fields
-from trytond.pool import PoolMeta
-
-from . import luhn
-from .exceptions import SIRETValidationError
+from trytond.pool import Pool, PoolMeta
+from trytond.transaction import Transaction
 
 
 class Address(metaclass=PoolMeta):
     __name__ = 'party.address'
 
-    siret_nic = fields.Char("SIRET NIC", select=True, size=5)
-    siret = fields.Function(fields.Char('SIRET'), 'get_siret')
-
-    def get_siret(self, name):
-        if self.party.siren and self.siret_nic:
-            return self.party.siren + self.siret_nic
+    siret = fields.Function(fields.Many2One(
+            'party.identifier', "SIRET"),
+        'get_siret', searcher='search_siret')
 
     @classmethod
-    def validate(cls, addresses):
-        super(Address, cls).validate(addresses)
-        for address in addresses:
-            address.check_siret()
+    def __register__(cls, module):
+        pool = Pool()
+        Party = pool.get('party.party')
+        Identifier = pool.get('party.identifier')
+        cursor = Transaction().connection.cursor()
+        party = Party.__table__()
+        address = cls.__table__()
+        identifier = Identifier.__table__()
+
+        super().__register__(module)
+
+        table_h = cls.__table_handler__(module)
+        party_h = Party.__table_handler__(module)
 
-    def check_siret(self):
-        '''
-        Check validity of SIRET
-        '''
-        if self.siret:
-            if (len(self.siret) != 14
-                    or not luhn.validate(self.siret)):
-                raise SIRETValidationError(
-                    gettext('party_siret.msg_invalid_siret',
-                        number=self.siret,
-                        address=self.rec_name))
+        # Migrate from 6.2: replace siren and siret by identifier
+        if party_h.column_exist('siren'):
+            cursor.execute(*identifier.insert(
+                    [identifier.party,
+                        identifier.type, identifier.code,
+                        identifier.active],
+                    party.select(
+                        party.id, Literal('fr_siren'),
+                        party.siren, party.active,
+                        where=(party.siren != Null)
+                        & (party.siren != ''))))
+            if table_h.column_exist('siret_nic'):
+                cursor.execute(*identifier.insert(
+                        [identifier.party, identifier.address,
+                            identifier.type, identifier.code,
+                            identifier.active],
+                        address.join(
+                            party, condition=address.party == party.id
+                            ).select(
+                            address.party, address.id,
+                            Literal('fr_siret'),
+                            Concat(party.siren, address.siret_nic),
+                            address.active,
+                            where=(address.siret_nic != Null)
+                            & (address.siret_nic != '')
+                            & (party.siren != Null)
+                            & (party.siren != ''))))
+                table_h.drop_column('siret_nic')
+            party_h.drop_column('siren')
+
+    def get_siret(self, name):
+        for identifier in self.identifiers:
+            if identifier.type == 'fr_siret':
+                return identifier.id
+
+    @classmethod
+    def search_siret(cls, name, clause):
+        _, operator, value = clause
+        domain = [
+            ('identifiers', 'where', [
+                    ('code', operator, value),
+                    ('type', 'in', 'fr_siren'),
+                    ]),
+            ]
+        # Add party without tax identifier
+        if ((operator == '=' and value is None)
+                or (operator == 'in' and None in value)):
+            domain = ['OR',
+                domain, [
+                    ('identifiers', 'not where', [
+                            ('type', '=', 'fr_siren'),
+                            ]),
+                    ],
+                ]
+        return domain
diff -r e253d14b3240 -r f5c2c4885143 address.xml
--- a/address.xml       Thu Feb 03 23:13:26 2022 +0100
+++ b/address.xml       Sun Feb 13 00:43:49 2022 +0100
@@ -8,10 +8,5 @@
             <field name="inherit" ref="party.address_view_tree"/>
             <field name="name">address_tree</field>
         </record>
-        <record model="ir.ui.view" id="address_view_form">
-            <field name="model">party.address</field>
-            <field name="inherit" ref="party.address_view_form"/>
-            <field name="name">address_form</field>
-        </record>
     </data>
 </tryton>
diff -r e253d14b3240 -r f5c2c4885143 exceptions.py
--- a/exceptions.py     Thu Feb 03 23:13:26 2022 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-# This file is part of Tryton.  The COPYRIGHT file at the top level of
-# this repository contains the full copyright notices and license terms.
-
-from trytond.model.exceptions import ValidationError
-
-
-class SIRENValidationError(ValidationError):
-    pass
-
-
-class SIRETValidationError(SIRENValidationError):
-    pass
diff -r e253d14b3240 -r f5c2c4885143 luhn.py
--- a/luhn.py   Thu Feb 03 23:13:26 2022 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-# This file is part of Tryton.  The COPYRIGHT file at the top level of
-# this repository contains the full copyright notices and license terms.
-
-
-def validate(value):
-    """
-    Validate value with Luhn algorithm
-    :param value: the value
-    :return: a boolean
-    """
-    if not isinstance(value, str):
-        value = str(value)
-    try:
-        evens = sum(int(x) for x in value[-1::-2])
-        odds = sum(sum(divmod(int(x) * 2, 10)) for x in value[-2::-2])
-        return (evens + odds) % 10 == 0
-    except ValueError:
-        return False
diff -r e253d14b3240 -r f5c2c4885143 message.xml
--- a/message.xml       Thu Feb 03 23:13:26 2022 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-<?xml version="1.0"?>
-<!-- This file is part of Tryton.  The COPYRIGHT file at the top level of
-this repository contains the full copyright notices and license terms. -->
-<tryton>
-    <data grouped="1">
-        <record model="ir.message" id="msg_invalid_siren">
-            <field name="text">The SIREN number "%(number)s" for party 
"%(party)s" is not valid.</field>
-        </record>
-        <record model="ir.message" id="msg_invalid_siret">
-            <field name="text">The SIRET number "%(number)s" for address 
"%(address)s" is not valid.</field>
-        </record>
-    </data>
-</tryton>
diff -r e253d14b3240 -r f5c2c4885143 party.py
--- a/party.py  Thu Feb 03 23:13:26 2022 +0100
+++ b/party.py  Sun Feb 13 00:43:49 2022 +0100
@@ -1,31 +1,38 @@
 # This file is part of Tryton.  The COPYRIGHT file at the top level of
 # this repository contains the full copyright notices and license terms.
-from trytond.i18n import gettext
 from trytond.model import fields
 from trytond.pool import PoolMeta
 
-from . import luhn
-from .exceptions import SIRENValidationError
-
 
 class Party(metaclass=PoolMeta):
     __name__ = 'party.party'
 
-    siren = fields.Char("SIREN", select=True, size=9)
+    siren = fields.Function(fields.Many2One(
+            'party.identifier', "SIREN"),
+        'get_siren', searcher='search_siren')
+
+    def get_siren(self, name):
+        for identifier in self.identifiers:
+            if identifier.type == 'fr_siren':
+                return identifier.id
 
     @classmethod
-    def validate(cls, parties):
-        super(Party, cls).validate(parties)
-        for party in parties:
-            party.check_siren()
-
-    def check_siren(self):
-        '''
-        Check validity of SIREN
-        '''
-        if self.siren:
-            if len(self.siren) != 9 or not luhn.validate(self.siren):
-                raise SIRENValidationError(
-                    gettext('party_siret.msg_invalid_siren',
-                        number=self.siren,
-                        party=self.rec_name))
+    def search_siren(cls, name, clause):
+        _, operator, value = clause
+        domain = [
+            ('identifiers', 'where', [
+                    ('code', operator, value),
+                    ('type', 'in', 'fr_siren'),
+                    ]),
+            ]
+        # Add party without tax identifier
+        if ((operator == '=' and value is None)
+                or (operator == 'in' and None in value)):
+            domain = ['OR',
+                domain, [
+                    ('identifiers', 'not where', [
+                            ('type', '=', 'fr_siren'),
+                            ]),
+                    ],
+                ]
+        return domain
diff -r e253d14b3240 -r f5c2c4885143 party.xml
--- a/party.xml Thu Feb 03 23:13:26 2022 +0100
+++ b/party.xml Sun Feb 13 00:43:49 2022 +0100
@@ -8,10 +8,5 @@
             <field name="inherit" ref="party.party_view_tree"/>
             <field name="name">party_tree</field>
         </record>
-        <record model="ir.ui.view" id="party_view_form">
-            <field name="model">party.party</field>
-            <field name="inherit" ref="party.party_view_form"/>
-            <field name="name">party_form</field>
-        </record>
     </data>
 </tryton>
diff -r e253d14b3240 -r f5c2c4885143 tests/test_party_siret.py
--- a/tests/test_party_siret.py Thu Feb 03 23:13:26 2022 +0100
+++ b/tests/test_party_siret.py Sun Feb 13 00:43:49 2022 +0100
@@ -3,7 +3,6 @@
 import unittest
 
 import trytond.tests.test_tryton
-from trytond.modules.party_siret import luhn
 from trytond.tests.test_tryton import ModuleTestCase
 
 
@@ -11,32 +10,6 @@
     'Test PartySiret module'
     module = 'party_siret'
 
-    def test_luhn(self):
-        'Test luhn'
-        values = (
-            (4111111111111111, True),
-            ('4111111111111111', True),
-            (4222222222222, True),
-            (378734493671000, True),
-            (5424000000000015, True),
-            (5555555555554444, True),
-            (1008, True),
-            ('0000001008', True),
-            ('000000001008', True),
-            (4012888888881881, True),
-            (1234567890123456789012345678909, True),
-            (4111111111211111, False),
-            (42222222222224, False),
-            (100, False),
-            ('100', False),
-            ('0000100', False),
-            ('abc', False),
-            (None, False),
-            (object(), False),
-            )
-        for value, test in values:
-            self.assertTrue(luhn.validate(value) == test)
-
 
 def suite():
     suite = trytond.tests.test_tryton.suite()
diff -r e253d14b3240 -r f5c2c4885143 tryton.cfg
--- a/tryton.cfg        Thu Feb 03 23:13:26 2022 +0100
+++ b/tryton.cfg        Sun Feb 13 00:43:49 2022 +0100
@@ -6,4 +6,3 @@
 xml:
     party.xml
     address.xml
-    message.xml
diff -r e253d14b3240 -r f5c2c4885143 view/address_form.xml
--- a/view/address_form.xml     Thu Feb 03 23:13:26 2022 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-<?xml version="1.0"?>
-<!-- This file is part of Tryton.  The COPYRIGHT file at the top level of
-this repository contains the full copyright notices and license terms. -->
-<data>
-    <xpath expr="/form/field[@name='name']" position="after">
-        <group id="siret" colspan="2" col="-1">
-            <label name="siret_nic"/>
-            <field name="siret_nic"/>
-            <label name="siret"/>
-            <field name="siret"/>
-        </group>
-    </xpath>
-</data>
diff -r e253d14b3240 -r f5c2c4885143 view/party_form.xml
--- a/view/party_form.xml       Thu Feb 03 23:13:26 2022 +0100
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-<?xml version="1.0"?>
-<!-- This file is part of Tryton.  The COPYRIGHT file at the top level of
-this repository contains the full copyright notices and license terms. -->
-<data>
-    <xpath expr="//page[@name='identifiers']/field[@name='identifiers']" 
position="before">
-        <label name="siren"/>
-        <field name="siren"/>
-        <newline/>
-    </xpath>
-</data>

Reply via email to