changeset a26c39a4b0d5 in modules/country:default
details: https://hg.tryton.org/modules/country?cmd=changeset&node=a26c39a4b0d5
description:
Add UN M49 regions
issue11669
review423711003
diffstat:
CHANGELOG | 1 +
__init__.py | 1 +
country.py | 40 ++++++++-
country.xml | 114 ++++++++++++++++++++++-
doc/design.rst | 24 ++++-
region.xml | 206 ++++++++++++++++++++++++++++++++++++++++++++
scripts/import_countries.py | 61 +++++++++++++
tryton.cfg | 1 +
view/country_form.xml | 4 +-
view/country_tree.xml | 5 +-
view/region_form.xml | 16 +++
view/region_list.xml | 7 +
view/region_tree.xml | 7 +
13 files changed, 474 insertions(+), 13 deletions(-)
diffs (635 lines):
diff -r 2ab9fb13824c -r a26c39a4b0d5 CHANGELOG
--- a/CHANGELOG Thu Sep 08 13:33:44 2022 +0200
+++ b/CHANGELOG Mon Sep 12 21:31:06 2022 +0200
@@ -1,3 +1,4 @@
+* Add UN M49 regions
* Add flag symbol for country and subdivision
Version 6.4.0 - 2022-05-02
diff -r 2ab9fb13824c -r a26c39a4b0d5 __init__.py
--- a/__init__.py Thu Sep 08 13:33:44 2022 +0200
+++ b/__init__.py Mon Sep 12 21:31:06 2022 +0200
@@ -8,6 +8,7 @@
# Prevent to import backend when importing scripts
from . import country
Pool.register(
+ country.Region,
country.Country,
country.Subdivision,
country.PostalCode,
diff -r 2ab9fb13824c -r a26c39a4b0d5 country.py
--- a/country.py Thu Sep 08 13:33:44 2022 +0200
+++ b/country.py Mon Sep 12 21:31:06 2022 +0200
@@ -1,13 +1,49 @@
# 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 import backend
-from trytond.model import DeactivableMixin, ModelSQL, ModelView, fields
+from trytond.model import DeactivableMixin, ModelSQL, ModelView, fields, tree
from trytond.pool import Pool
from trytond.pyson import Eval
from trytond.tools import lstrip_wildcard
from trytond.transaction import Transaction
+class Region(tree(), ModelSQL, ModelView):
+ "Region"
+ __name__ = 'country.region'
+
+ name = fields.Char("Name", required=True, translate=True)
+ code_numeric = fields.Char(
+ "Numeric Code", size=3,
+ help="UN M49 region code.")
+ parent = fields.Many2One('country.region', "Parent")
+ subregions = fields.One2Many('country.region', 'parent', "Subregions")
+ countries = fields.One2Many(
+ 'country.country', 'region', "Countries",
+ add_remove=[
+ ('region', '=', None),
+ ])
+
+ @classmethod
+ def __setup__(cls):
+ super().__setup__()
+ cls._order.insert(0, ('name', 'ASC'))
+
+ @classmethod
+ def search_rec_name(cls, name, clause):
+ if clause[1].startswith('!') or clause[1].startswith('not '):
+ bool_op = 'AND'
+ else:
+ bool_op = 'OR'
+ code_value = clause[2]
+ if clause[1].endswith('like'):
+ code_value = lstrip_wildcard(clause[2])
+ return [bool_op,
+ ('name',) + tuple(clause[1:]),
+ ('code_numeric', clause[1], code_value) + tuple(clause[3:]),
+ ]
+
+
class Country(DeactivableMixin, ModelSQL, ModelView):
'Country'
__name__ = 'country.country'
@@ -20,6 +56,8 @@
code_numeric = fields.Char('Numeric Code', select=True,
help="The ISO numeric country code.")
flag = fields.Function(fields.Char("Flag"), 'on_change_with_flag')
+ region = fields.Many2One(
+ 'country.region', "Region", ondelete='SET NULL')
subdivisions = fields.One2Many('country.subdivision',
'country', 'Subdivisions')
diff -r 2ab9fb13824c -r a26c39a4b0d5 country.xml
--- a/country.xml Thu Sep 08 13:33:44 2022 +0200
+++ b/country.xml Mon Sep 12 21:31:06 2022 +0200
@@ -8,6 +8,96 @@
<field name="path">icons/tryton-country.svg</field>
</record>
+ <menuitem
+ name="Countries"
+ parent="ir.menu_administration"
+ sequence="30"
+ id="menu_country"
+ icon="tryton-country"/>
+ <record model="ir.ui.menu-res.group"
+ id="menu_country_group_admin">
+ <field name="menu" ref="menu_country"/>
+ <field name="group" ref="res.group_admin"/>
+ </record>
+
+ <record model="ir.ui.view" id="region_view_form">
+ <field name="model">country.region</field>
+ <field name="type">form</field>
+ <field name="name">region_form</field>
+ </record>
+
+ <record model="ir.ui.view" id="region_view_list">
+ <field name="model">country.region</field>
+ <field name="type">tree</field>
+ <field name="priority" eval="10"/>
+ <field name="name">region_list</field>
+ </record>
+
+ <record model="ir.ui.view" id="region_view_tree">
+ <field name="model">country.region</field>
+ <field name="type">tree</field>
+ <field name="priority" eval="20"/>
+ <field name="field_childs">subregions</field>
+ <field name="name">region_tree</field>
+ </record>
+
+ <record model="ir.action.act_window" id="act_region_tree">
+ <field name="name">Areas</field>
+ <field name="res_model">country.region</field>
+ <field name="domain" eval="[('parent', '=', None)]" pyson="1"/>
+ </record>
+ <record model="ir.action.act_window.view" id="act_region_tree_view1">
+ <field name="sequence" eval="10"/>
+ <field name="view" ref="region_view_tree"/>
+ <field name="act_window" ref="act_region_tree"/>
+ </record>
+ <record model="ir.action.act_window.view" id="act_region_tree_view2">
+ <field name="sequence" eval="20"/>
+ <field name="view" ref="region_view_form"/>
+ <field name="act_window" ref="act_region_tree"/>
+ </record>
+ <menuitem
+ parent="menu_country"
+ action="act_region_tree"
+ sequence="20"
+ id="menu_region_tree"/>
+
+ <record model="ir.action.act_window" id="act_region_form">
+ <field name="name">Regions</field>
+ <field name="res_model">country.region</field>
+ </record>
+ <record model="ir.action.act_window.view" id="act_region_form_view1">
+ <field name="sequence" eval="10"/>
+ <field name="view" ref="region_view_list"/>
+ <field name="act_window" ref="act_region_form"/>
+ </record>
+ <record model="ir.action.act_window.view" id="act_region_form_view2">
+ <field name="sequence" eval="20"/>
+ <field name="view" ref="region_view_form"/>
+ <field name="act_window" ref="act_region_form"/>
+ </record>
+ <menuitem
+ parent="menu_region_tree"
+ action="act_region_form"
+ sequence="10"
+ id="menu_region_form"/>
+
+ <record model="ir.model.access" id="access_region">
+ <field name="model" search="[('model', '=', 'country.region')]"/>
+ <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_region_admin">
+ <field name="model" search="[('model', '=', 'country.region')]"/>
+ <field name="group" ref="res.group_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>
+
<record model="ir.ui.view" id="country_view_form">
<field name="model">country.country</field>
<field name="type">form</field>
@@ -33,15 +123,23 @@
<field name="act_window" ref="act_country_form"/>
</record>
<menuitem
- parent="ir.menu_administration"
+ parent="menu_country"
action="act_country_form"
- sequence="30"
- id="menu_country_form"
- icon="tryton-country"/>
- <record model="ir.ui.menu-res.group"
- id="menu_country_form_group_admin">
- <field name="menu" ref="menu_country_form"/>
- <field name="group" ref="res.group_admin"/>
+ sequence="10"
+ id="menu_country_form"/>
+
+ <record model="ir.action.act_window" id="act_country_by_region">
+ <field name="name">Countries by Region</field>
+ <field name="res_model">country.country</field>
+ <field
+ name="domain"
+ eval="[('region', 'child_of', Eval('active_ids', []),
'parent')]"
+ pyson="1"/>
+ </record>
+ <record model="ir.action.keyword" id="act_country_by_region_keyword1">
+ <field name="keyword">tree_open</field>
+ <field name="model">country.region,-1</field>
+ <field name="action" ref="act_country_by_region"/>
</record>
<record model="ir.model.access" id="access_country">
diff -r 2ab9fb13824c -r a26c39a4b0d5 doc/design.rst
--- a/doc/design.rst Thu Sep 08 13:33:44 2022 +0200
+++ b/doc/design.rst Mon Sep 12 21:31:06 2022 +0200
@@ -4,6 +4,26 @@
The *Country Module* introduces the following concepts:
+.. _model-country.region:
+
+Region
+======
+
+The *Region* represents a geographical region that groups `Countries
<model-country.country>`.
+The main usage is for reporting and statistics.
+
+The `UN M49 <https://unstats.un.org/unsd/methodology/m49/>`_ methodology and
+codes are used when `Loading and updating countries and subdivisions`.
+
+.. seealso::
+
+ Regions can be found under the main menu entry:
+
+ |Administration --> Countries --> Regions|__
+
+ .. |Administration --> Countries --> Regions| replace::
:menuselection:`Administration --> Countries --> Regions`
+ __ https://demo.tryton.org/model/country.region
+
.. _model-country.country:
Country
@@ -20,9 +40,9 @@
Countries can be found under the main menu entry:
- |Administration --> Countries|__
+ |Administration --> Countries --> Countries|__
- .. |Administration --> Countries| replace::
:menuselection:`Administration --> Countries`
+ .. |Administration --> Countries --> Countries| replace::
:menuselection:`Administration --> Countries`
__ https://demo.tryton.org/model/country.country
.. _model-country.subdivision:
diff -r 2ab9fb13824c -r a26c39a4b0d5 region.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/region.xml Mon Sep 12 21:31:06 2022 +0200
@@ -0,0 +1,206 @@
+<?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="country.region" id="region_world">
+ <field name="name">World</field>
+ <field name="code_numeric">001</field>
+ </record>
+ </data>
+ <data grouped="1">
+ <record model="country.region" id="region_africa">
+ <field name="name">Africa</field>
+ <field name="code_numeric">002</field>
+ <field name="parent" ref="region_world"/>
+ </record>
+
+ <record model="country.region" id="region_antarctica">
+ <field name="name">Antarctica</field>
+ <field name="code_numeric">010</field>
+ <field name="parent" ref="region_world"/>
+ </record>
+
+ <record model="country.region" id="region_americas">
+ <field name="name">Americas</field>
+ <field name="code_numeric">019</field>
+ <field name="parent" ref="region_world"/>
+ </record>
+
+ <record model="country.region" id="region_asia">
+ <field name="name">Asia</field>
+ <field name="code_numeric">142</field>
+ <field name="parent" ref="region_world"/>
+ </record>
+
+ <record model="country.region" id="region_europe">
+ <field name="name">Europe</field>
+ <field name="code_numeric">150</field>
+ <field name="parent" ref="region_world"/>
+ </record>
+
+ <record model="country.region" id="region_oceania">
+ <field name="name">Oceania</field>
+ <field name="code_numeric">009</field>
+ <field name="parent" ref="region_world"/>
+ </record>
+ </data>
+ <data grouped="1">
+ <record model="country.region" id="region_northern_africa">
+ <field name="name">Northern Africa</field>
+ <field name="code_numeric">015</field>
+ <field name="parent" ref="region_africa"/>
+ </record>
+
+ <record model="country.region" id="region_sub-saharan_africa">
+ <field name="name">Sub-Saharan Africa</field>
+ <field name="code_numeric">202</field>
+ <field name="parent" ref="region_africa"/>
+ </record>
+
+ <record model="country.region" id="region_north_america">
+ <field name="name">North America</field>
+ <field name="code_numeric">003</field>
+ <field name="parent" ref="region_americas"/>
+ </record>
+
+ <record model="country.region" id="region_latin_america_caribbean">
+ <field name="name">Latin America and the Caribbean</field>
+ <field name="code_numeric">419</field>
+ <field name="parent" ref="region_americas"/>
+ </record>
+
+ <record model="country.region" id="region_eastern_asia">
+ <field name="name">Eastern Asia</field>
+ <field name="code_numeric">030</field>
+ <field name="parent" ref="region_asia"/>
+ </record>
+
+ <record model="country.region" id="region_southern_asia">
+ <field name="name">Southern Asia</field>
+ <field name="code_numeric">034</field>
+ <field name="parent" ref="region_asia"/>
+ </record>
+
+ <record model="country.region" id="region_south-eastern_asia">
+ <field name="name">South-eastern Asia</field>
+ <field name="code_numeric">035</field>
+ <field name="parent" ref="region_asia"/>
+ </record>
+
+ <record model="country.region" id="region_central_asia">
+ <field name="name">Central Asia</field>
+ <field name="code_numeric">143</field>
+ <field name="parent" ref="region_asia"/>
+ </record>
+
+ <record model="country.region" id="region_western_asia">
+ <field name="name">Western Asia</field>
+ <field name="code_numeric">145</field>
+ <field name="parent" ref="region_asia"/>
+ </record>
+
+ <record model="country.region" id="region_southern_europe">
+ <field name="name">Southern Europe</field>
+ <field name="code_numeric">039</field>
+ <field name="parent" ref="region_europe"/>
+ </record>
+
+ <record model="country.region" id="region_eastern_europe">
+ <field name="name">Eastern Europe</field>
+ <field name="code_numeric">151</field>
+ <field name="parent" ref="region_europe"/>
+ </record>
+
+ <record model="country.region" id="region_northern_europe">
+ <field name="name">Northern Europe</field>
+ <field name="code_numeric">154</field>
+ <field name="parent" ref="region_europe"/>
+ </record>
+
+ <record model="country.region" id="region_western_europe">
+ <field name="name">Western Europe</field>
+ <field name="code_numeric">155</field>
+ <field name="parent" ref="region_europe"/>
+ </record>
+
+ <record model="country.region" id="region_australia_new_zealand">
+ <field name="name">Australia and New Zealand</field>
+ <field name="code_numeric">053</field>
+ <field name="parent" ref="region_oceania"/>
+ </record>
+
+ <record model="country.region" id="region_melanesia">
+ <field name="name">Melanesia</field>
+ <field name="code_numeric">054</field>
+ <field name="parent" ref="region_oceania"/>
+ </record>
+
+ <record model="country.region" id="region_micronesia">
+ <field name="name">Micronesia</field>
+ <field name="code_numeric">057</field>
+ <field name="parent" ref="region_oceania"/>
+ </record>
+
+ <record model="country.region" id="region_polynesia">
+ <field name="name">Polynesia</field>
+ <field name="code_numeric">061</field>
+ <field name="parent" ref="region_oceania"/>
+ </record>
+ </data>
+ <data grouped="1">
+ <record model="country.region" id="region_western_africa">
+ <field name="name">Western Africa</field>
+ <field name="code_numeric">011</field>
+ <field name="parent" ref="region_sub-saharan_africa"/>
+ </record>
+
+ <record model="country.region" id="region_eastern_africa">
+ <field name="name">Eastern Africa</field>
+ <field name="code_numeric">014</field>
+ <field name="parent" ref="region_sub-saharan_africa"/>
+ </record>
+
+ <record model="country.region" id="region_middle_africa">
+ <field name="name">Middle Africa</field>
+ <field name="code_numeric">017</field>
+ <field name="parent" ref="region_sub-saharan_africa"/>
+ </record>
+
+ <record model="country.region" id="region_southern_africa">
+ <field name="name">Southern Africa</field>
+ <field name="code_numeric">018</field>
+ <field name="parent" ref="region_sub-saharan_africa"/>
+ </record>
+
+ <record model="country.region" id="region_northern_america">
+ <field name="name">Northern America</field>
+ <field name="code_numeric">021</field>
+ <field name="parent" ref="region_north_america"/>
+ </record>
+
+ <record model="country.region" id="region_south_america">
+ <field name="name">South America</field>
+ <field name="code_numeric">005</field>
+ <field name="parent" ref="region_latin_america_caribbean"/>
+ </record>
+
+ <record model="country.region" id="region_central_america">
+ <field name="name">Central America</field>
+ <field name="code_numeric">013</field>
+ <field name="parent" ref="region_latin_america_caribbean"/>
+ </record>
+
+ <record model="country.region" id="region_caribbean">
+ <field name="name">Caribbean</field>
+ <field name="code_numeric">029</field>
+ <field name="parent" ref="region_latin_america_caribbean"/>
+ </record>
+
+ <record model="country.region" id="region_channel_islands">
+ <field name="name">Channel Islands</field>
+ <field name="code_numeric">830</field>
+ <field name="parent" ref="region_northern_europe"/>
+ </record>
+ </data>
+</tryton>
diff -r 2ab9fb13824c -r a26c39a4b0d5 scripts/import_countries.py
--- a/scripts/import_countries.py Thu Sep 08 13:33:44 2022 +0200
+++ b/scripts/import_countries.py Mon Sep 12 21:31:06 2022 +0200
@@ -25,6 +25,63 @@
prog = os.path.basename(sys.argv[0])
sys.exit("proteus must be installed to use %s" % prog)
+SUBREGIONS = {
+ '001': ['002', '009', '010', '019', '142', '150'],
+ '002': ['015', '202'],
+ '015': ['012', '434', '504', '729', '732', '788', '818'],
+ '202': ['011', '014', '017', '018'],
+ '011': [
+ '132', '204', '270', '288', '324', '384', '430', '466', '478', '562',
+ '566', '624', '654', '686', '694', '768', '854'],
+ '014': [
+ '086', '108', '174', '175', '231', '232', '260', '262', '404', '450',
+ '454', '480', '508', '638', '646', '690', '706', '716', '728', '800',
+ '834', '894'],
+ '017': ['024', '120', '140', '148', '178', '180', '226', '266', '678'],
+ '018': ['072', '426', '516', '710', '748'],
+ '010': [],
+ '019': ['003', '419'],
+ '003': ['013', '021', '029'],
+ '021': ['060', '124', '304', '666', '840'],
+ '419': ['005', '013', '029'],
+ '005': [
+ '032', '068', '074', '076', '152', '170', '218', '238', '239', '254',
+ '328', '600', '604', '740', '858', '862'],
+ '013': ['084', '188', '222', '320', '340', '484', '558', '591'],
+ '029': [
+ '028', '044', '052', '092', '136', '192', '212', '214', '308', '312',
+ '332', '388', '474', '500', '531', '533', '534', '535', '630', '652',
+ '659', '660', '662', '663', '670', '780', '796', '850'],
+ '142': ['030', '034', '035', '143', '145'],
+ '030': ['156', '344', '392', '408', '410', '446', '496'] + ['158'],
+ '034': ['004', '050', '064', '144', '356', '364', '462', ' 524', '586'],
+ '035': [
+ '096', '104', '116', '360', '418', '458', '608', '626', '702', '704',
+ '764'],
+ '143': ['398', '417', '762', '795', '860'],
+ '145': [
+ '031', '051', '048', '196', '268', '275', '368', '376', '400', '414',
+ '422', '512', '634', '682', '760', '792', '784', '887'],
+ '150': ['039', '151', '154', '155'],
+ '039': [
+ '008', '020', '070', '191', '292', '300', '336', '380', '470', '499',
+ '620', '674', '688', '705', '724', '807'],
+ '151': [
+ '100', '112', '203', '348', '498', '616', '642', '643', '703', '804'],
+ '154': [
+ '208', '233', '234', '246', '248', '352', '372', '428', '440', '578',
+ '744', '752', '826', '833', '830'],
+ '830': ['831', '832', '680'],
+ '155': ['040', '056', '250', '276', '438', '442', '492', '528', '756'],
+ '009': ['053', '054', '057', '061'],
+ '053': ['036', '162', '166', '334', '554', '574'],
+ '054': ['090', '242', '540', '548', '598'],
+ '057': ['296', '316', '520', '580', '581', '583', '584', '585'],
+ '061': [
+ '016', '184', '258', '570', '612', '772', '776', '798', '876', '882'],
+ }
+REGION2PARENT = {c: p for p, r in SUBREGIONS.items() for c in r}
+
def _progress(iterable):
if ProgressBar:
@@ -54,8 +111,11 @@
def update_countries(countries):
print("Update countries", file=sys.stderr)
+ Region = Model.get('country.region')
Country = Model.get('country.country')
+ code2region = {a.code_numeric: a for a in Region.find([])}
+
records = []
for country in _progress(pycountry.countries):
code = country.alpha_2
@@ -66,6 +126,7 @@
record.name = _remove_forbidden_chars(country.name)
record.code3 = country.alpha_3
record.code_numeric = country.numeric
+ record.region = code2region.get(REGION2PARENT.get(country.numeric))
records.append(record)
Country.save(records)
diff -r 2ab9fb13824c -r a26c39a4b0d5 tryton.cfg
--- a/tryton.cfg Thu Sep 08 13:33:44 2022 +0200
+++ b/tryton.cfg Mon Sep 12 21:31:06 2022 +0200
@@ -5,3 +5,4 @@
res
xml:
country.xml
+ region.xml
diff -r 2ab9fb13824c -r a26c39a4b0d5 view/country_form.xml
--- a/view/country_form.xml Thu Sep 08 13:33:44 2022 +0200
+++ b/view/country_form.xml Mon Sep 12 21:31:06 2022 +0200
@@ -4,9 +4,11 @@
<form col="6">
<label name="name"/>
<field name="name"/>
+ <label name="region"/>
+ <field name="region"/>
<label name="active"/>
<field name="active"/>
- <newline/>
+
<label name="code"/>
<field name="code"/>
<label name="code3"/>
diff -r 2ab9fb13824c -r a26c39a4b0d5 view/country_tree.xml
--- a/view/country_tree.xml Thu Sep 08 13:33:44 2022 +0200
+++ b/view/country_tree.xml Mon Sep 12 21:31:06 2022 +0200
@@ -2,8 +2,11 @@
<!-- 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="name" expand="1">
+ <field name="name" expand="2">
<prefix name="flag"/>
</field>
<field name="code" optional="1"/>
+ <field name="code3" optional="1"/>
+ <field name="code_numeric" optional="1"/>
+ <field name="region" expand="1" optional="1"/>
</tree>
diff -r 2ab9fb13824c -r a26c39a4b0d5 view/region_form.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/view/region_form.xml Mon Sep 12 21:31:06 2022 +0200
@@ -0,0 +1,16 @@
+<?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="name"/>
+ <field name="name"/>
+ <label name="code_numeric"/>
+ <field name="code_numeric"/>
+
+ <label name="parent"/>
+ <field name="parent"/>
+
+ <field name="subregions" colspan="4"/>
+
+ <field name="countries" colspan="4"/>
+</form>
diff -r 2ab9fb13824c -r a26c39a4b0d5 view/region_list.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/view/region_list.xml Mon Sep 12 21:31:06 2022 +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="name" expand="1"/>
+ <field name="code_numeric" optional="1"/>
+</tree>
diff -r 2ab9fb13824c -r a26c39a4b0d5 view/region_tree.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/view/region_tree.xml Mon Sep 12 21:31:06 2022 +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 keyword_open="1">
+ <field name="name" expand="1"/>
+ <field name="code_numeric" optional="1"/>
+</tree>