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>