changeset 15ef94c7a85e in modules/party:default
details: https://hg.tryton.org/modules/party?cmd=changeset;node=15ef94c7a85e
description:
        Limit subdivision types on address

        issue7554
        review49501002
diffstat:

 CHANGELOG                              |   1 +
 __init__.py                            |   1 +
 address.py                             |  94 +++++++++++++++++++++++++++++++--
 address.xml                            |  71 +++++++++++++++++++++++++-
 doc/index.rst                          |   5 +
 message.xml                            |   3 +
 view/address_subdivision_type_form.xml |  11 +++
 view/address_subdivision_type_list.xml |   7 ++
 8 files changed, 185 insertions(+), 8 deletions(-)

diffs (323 lines):

diff -r 229618843afd -r 15ef94c7a85e CHANGELOG
--- a/CHANGELOG Sat Sep 28 23:59:09 2019 +0200
+++ b/CHANGELOG Tue Oct 08 18:57:22 2019 +0200
@@ -1,3 +1,4 @@
+* Limit subdivision types on address
 * Add call url for mobile contact mechanisms
 * Replace country and language in address format by codes
 * Add sequence field to contact mechanism form view
diff -r 229618843afd -r 15ef94c7a85e __init__.py
--- a/__init__.py       Sat Sep 28 23:59:09 2019 +0200
+++ b/__init__.py       Tue Oct 08 18:57:22 2019 +0200
@@ -21,6 +21,7 @@
         party.PartyEraseAsk,
         address.Address,
         address.AddressFormat,
+        address.SubdivisionType,
         contact_mechanism.ContactMechanism,
         configuration.Configuration,
         configuration.ConfigurationSequence,
diff -r 229618843afd -r 15ef94c7a85e address.py
--- a/address.py        Sat Sep 28 23:59:09 2019 +0200
+++ b/address.py        Tue Oct 08 18:57:22 2019 +0200
@@ -5,12 +5,12 @@
 
 from sql.conditionals import Coalesce
 from sql.functions import Substring
-from sql.operators import Concat
+from sql.operators import Concat, Equal
 
 from trytond.i18n import gettext
 from trytond.model import (
     ModelView, ModelSQL, MatchMixin, DeactivableMixin, fields,
-    sequence_ordered)
+    sequence_ordered, Exclude)
 from trytond.model.exceptions import AccessError
 from trytond.pyson import Eval, If
 from trytond.pool import Pool
@@ -19,8 +19,6 @@
 from trytond.cache import Cache
 from .exceptions import InvalidFormat
 
-__all__ = ['Address', 'AddressFormat']
-
 STATES = {
     'readonly': ~Eval('active'),
     }
@@ -44,12 +42,21 @@
     city = fields.Char('City', states=STATES, depends=DEPENDS)
     country = fields.Many2One('country.country', 'Country',
         states=STATES, depends=DEPENDS)
+    subdivision_types = fields.Function(
+        fields.MultiSelection(
+            'get_subdivision_types', "Subdivision Types"),
+        'on_change_with_subdivision_types')
     subdivision = fields.Many2One("country.subdivision",
-        'Subdivision', domain=[
+        'Subdivision',
+        domain=[
             ('country', '=', Eval('country', -1)),
-            ('parent', '=', None),
+            If(Eval('subdivision_types', []),
+                ('type', 'in', Eval('subdivision_types', [])),
+                ()
+                ),
             ],
-        states=STATES, depends=['active', 'country'])
+        states=STATES,
+        depends=['active', 'country', 'subdivision_types'])
     full_address = fields.Function(fields.Text('Full Address'),
             'get_full_address')
 
@@ -221,6 +228,18 @@
                 and self.subdivision.country != self.country):
             self.subdivision = None
 
+    @classmethod
+    def get_subdivision_types(cls):
+        pool = Pool()
+        Subdivision = pool.get('country.subdivision')
+        return Subdivision.fields_get(['type'])['type']['selection']
+
+    @fields.depends('country')
+    def on_change_with_subdivision_types(self, name=None):
+        pool = Pool()
+        Types = pool.get('party.address.subdivision_type')
+        return Types.get_types(self.country)
+
 
 class AddressFormat(DeactivableMixin, MatchMixin, ModelSQL, ModelView):
     "Address Format"
@@ -349,3 +368,64 @@
 
         cls._get_format_cache.set(key, format_)
         return format_
+
+
+class SubdivisionType(DeactivableMixin, ModelSQL, ModelView):
+    "Address Subdivision Type"
+    __name__ = 'party.address.subdivision_type'
+    country_code = fields.Char("Country Code", size=2, required=True)
+    types = fields.MultiSelection('get_subdivision_types', "Subdivision Types")
+    _get_types_cache = Cache('party.address.subdivision_type.get_types')
+
+    @classmethod
+    def __setup__(cls):
+        super().__setup__()
+        t = cls.__table__()
+        cls._sql_constraints = [
+            ('country_code_unique',
+                Exclude(t, (t.country_code, Equal),
+                    where=t.active == True),
+                'party.msg_address_subdivision_country_code_unique')
+            ]
+        cls._order.insert(0, ('country_code', 'ASC NULLS LAST'))
+
+    @classmethod
+    def get_subdivision_types(cls):
+        pool = Pool()
+        Subdivision = pool.get('country.subdivision')
+        return Subdivision.fields_get(['type'])['type']['selection']
+
+    @classmethod
+    def create(cls, *args, **kwargs):
+        records = super().create(*args, **kwargs)
+        cls._get_types_cache.clear()
+        return records
+
+    @classmethod
+    def write(cls, *args, **kwargs):
+        super().write(*args, **kwargs)
+        cls._get_types_cache.clear()
+
+    @classmethod
+    def delete(cls, *args, **kwargs):
+        super().delete(*args, **kwargs)
+        cls._get_types_cache.clear()
+
+    @classmethod
+    def get_types(cls, country):
+        key = country.code if country else None
+        types = cls._get_types_cache.get(key)
+        if types is not None:
+            return list(types)
+
+        records = cls.search([
+                ('country_code', '=', country.code if country else None),
+                ])
+        if records:
+            record, = records
+            types = record.types
+        else:
+            types = []
+
+        cls._get_types_cache.set(key, types)
+        return types
diff -r 229618843afd -r 15ef94c7a85e address.xml
--- a/address.xml       Sat Sep 28 23:59:09 2019 +0200
+++ b/address.xml       Tue Oct 08 18:57:22 2019 +0200
@@ -85,6 +85,51 @@
             <field name="perm_delete" eval="True"/>
         </record>
 
+        <record model="ir.ui.view" id="address_subdivision_type_view_list">
+            <field name="model">party.address.subdivision_type</field>
+            <field name="type">tree</field>
+            <field name="name">address_subdivision_type_list</field>
+        </record>
+
+        <record model="ir.ui.view" id="address_subdivision_type_view_form">
+            <field name="model">party.address.subdivision_type</field>
+            <field name="type">form</field>
+            <field name="name">address_subdivision_type_form</field>
+        </record>
+
+        <record model="ir.action.act_window" 
id="act_address_subdivision_type_form">
+            <field name="name">Address Subdivision Types</field>
+            <field name="res_model">party.address.subdivision_type</field>
+        </record>
+        <record model="ir.action.act_window.view" 
id="act_address_subdivision_type_form_view1">
+            <field name="sequence" eval="10"/>
+            <field name="view" ref="address_subdivision_type_view_list"/>
+            <field name="act_window" ref="act_address_subdivision_type_form"/>
+        </record>
+        <record model="ir.action.act_window.view" 
id="act_address_subdivision_type_form_view2">
+          <field name="sequence" eval="20"/>
+          <field name="view" ref="address_subdivision_type_view_form"/>
+          <field name="act_window" ref="act_address_subdivision_type_form"/>
+        </record>
+        <menuitem parent="menu_configuration" sequence="20"
+            action="act_address_subdivision_type_form" 
id="menu_address_subdivision_type_form"/>
+
+        <record model="ir.model.access" id="access_address_subdivision_type">
+            <field name="model" search="[('model', '=', 
'party.address.subdivision_type')]"/>
+            <field name="perm_read" eval="True"/>
+            <field name="perm_write" eval="False"/>
+            <field name="perm_create" eval="False"/>
+            <field name="perm_delete" eval="False"/>
+        </record>
+        <record model="ir.model.access" 
id="access_address_subdivision_type_admin">
+            <field name="model" search="[('model', '=', 
'party.address.subdivision_type')]"/>
+            <field name="group" ref="group_party_admin"/>
+            <field name="perm_read" eval="True"/>
+            <field name="perm_write" eval="True"/>
+            <field name="perm_create" eval="True"/>
+            <field name="perm_delete" eval="True"/>
+        </record>
+
     </data>
     <data noupdate="1" grouped="1">
         <!-- From https://en.wikipedia.org/wiki/Address_(geography) -->
@@ -159,6 +204,16 @@
 ${COUNTRY}</field>
         </record>
 
+        <record model="party.address.format" id="address_format_bg">
+            <field name="country_code">BG</field>
+            <field name="format_">${party_name}
+${street}
+${name}
+${zip} ${city}
+${subdivision}
+${COUNTRY}</field>
+        </record>
+
         <record model="party.address.format" id="address_format_ca_fr">
             <field name="country_code">CA</field>
             <field name="language_code">fr</field>
@@ -322,6 +377,11 @@
 ${COUNTRY}</field>
         </record>
 
+        <record model="party.address.subdivision_type" 
id="address_subdivision_type_id">
+            <field name="country_code">ID</field>
+            <field name="types" eval="['province', 'autonomous province', 
'special district', 'special region']"/>
+        </record>
+
         <record model="party.address.format" id="address_format_ir">
             <field name="country_code">IR</field>
             <field name="format_">${party_name}
@@ -369,6 +429,11 @@
 ${COUNTRY}</field>
         </record>
 
+        <record model="party.address.subdivision_type" 
id="address_subdivision_it">
+            <field name="country_code">IT</field>
+            <field name="types" eval="['province']"/>
+        </record>
+
         <record model="party.address.format" id="address_format_jp_jp">
             <field name="country_code">JP</field>
             <field name="language_code">jp</field>
@@ -608,6 +673,11 @@
 ${COUNTRY}</field>
         </record>
 
+        <record model="party.address.subdivision_type" 
id="address_subdivision_es">
+            <field name="country_code">ES</field>
+            <field name="types" eval="['province']"/>
+        </record>
+
         <record model="party.address.format" id="address_format_lk">
             <field name="country_code">LK</field>
             <field name="format_">${party_name}
@@ -706,6 +776,5 @@
 ${subdivision}
 ${COUNTRY}</field>
         </record>
-
     </data>
 </tryton>
diff -r 229618843afd -r 15ef94c7a85e doc/index.rst
--- a/doc/index.rst     Sat Sep 28 23:59:09 2019 +0200
+++ b/doc/index.rst     Tue Oct 08 18:57:22 2019 +0200
@@ -51,6 +51,11 @@
 It allows to define per country and language, how addresses should be
 formatted.
 
+Address Subdivision Type
+************************
+
+It allows to define for each country which types of subdivision are allowed on
+the address.
 
 Contact Mechanism
 *****************
diff -r 229618843afd -r 15ef94c7a85e message.xml
--- a/message.xml       Sat Sep 28 23:59:09 2019 +0200
+++ b/message.xml       Tue Oct 08 18:57:22 2019 +0200
@@ -36,5 +36,8 @@
         <record model="ir.message" id="msg_category_name_unique">
             <field name="text">The name of party category must be unique by 
parent.</field>
         </record>
+        <record model="ir.message" 
id="msg_address_subdivision_country_code_unique">
+            <field name="text">The country code on subdivision type must be 
unique.</field>
+        </record>
     </data>
 </tryton>
diff -r 229618843afd -r 15ef94c7a85e view/address_subdivision_type_form.xml
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/view/address_subdivision_type_form.xml    Tue Oct 08 18:57:22 2019 +0200
@@ -0,0 +1,11 @@
+<?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. -->
+<form>
+    <label name="country_code"/>
+    <field name="country_code"/>
+    <label name="active"/>
+    <field name="active"/>
+    <separator name="types" colspan="4"/>
+    <field name="types" colspan="4"/>
+</form>
diff -r 229618843afd -r 15ef94c7a85e view/address_subdivision_type_list.xml
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/view/address_subdivision_type_list.xml    Tue Oct 08 18:57:22 2019 +0200
@@ -0,0 +1,7 @@
+<?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. -->
+<tree>
+    <field name="country_code"/>
+    <field name="types" expand="1"/>
+</tree>

Reply via email to