diff --git a/modules/party/CHANGELOG b/modules/party/CHANGELOG
index aedbaf1dba..a2bda70f5c 100644
--- a/modules/party/CHANGELOG
+++ b/modules/party/CHANGELOG
@@ -1,3 +1,5 @@
+* Add structured address
+* Rename address name to building name
* Remove support for Python 3.8
* Add support for Python 3.13
* Notify for duplicate contact mechanism
diff --git a/modules/party/address.py b/modules/party/address.py
index 31afa8a5e5..9679611a01 100644
--- a/modules/party/address.py
+++ b/modules/party/address.py
@@ -1,6 +1,7 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
'Address'
+import re
from string import Template
from sql import Literal
@@ -33,8 +34,84 @@ class Address(
party_name = fields.Char(
"Party Name",
help="If filled, replace the name of the party for address formatting")
- name = fields.Char("Building Name")
- street = fields.Text("Street")
+
+ street = fields.Function(fields.Text(
+ "Street",
+ states={
+ 'readonly': (
+ Eval('street_name')
+ | Eval('building_number')
+ | Eval('unit_number')
+ | Eval('floor_number')
+ | Eval('room_number')
+ | Eval('post_box')
+ | Eval('post_office')
+ | Eval('private_bag')),
+ }),
+ 'on_change_with_street', setter='set_street', searcher='search_street')
+ street_unstructured = fields.Text(
+ "Street",
+ states={
+ 'invisible': (
+ (Eval('street_name')
+ | Eval('building_number')
+ | Eval('unit_number')
+ | Eval('floor_number')
+ | Eval('room_number')
+ | Eval('post_box')
+ | Eval('post_office')
+ | Eval('private_bag'))
+ & ~Eval('street_unstructured')),
+ })
+
+ street_name = fields.Char(
+ "Street Name",
+ states={
+ 'invisible': Eval('street_unstructured') & ~Eval('street_name'),
+ })
+ building_name = fields.Char(
+ "Building Name",
+ states={
+ 'invisible': Eval('street_unstructured') & ~Eval('building_name'),
+ })
+ building_number = fields.Char(
+ "Building Number",
+ states={
+ 'invisible': (
+ Eval('street_unstructured') & ~Eval('building_number')),
+ })
+ unit_number = fields.Char(
+ "Unit Number",
+ states={
+ 'invisible': Eval('street_unstructured') & ~Eval('unit_number'),
+ })
+ floor_number = fields.Char(
+ "Floor Number",
+ states={
+ 'invisible': Eval('street_unstructured') & ~Eval('floor_number'),
+ })
+ room_number = fields.Char(
+ "Room Number",
+ states={
+ 'invisible': Eval('street_unstructured') & ~Eval('room_number'),
+ })
+
+ post_box = fields.Char(
+ "Post Box",
+ states={
+ 'invisible': Eval('street_unstructured') & ~Eval('post_box'),
+ })
+ private_bag = fields.Char(
+ "Private Bag",
+ states={
+ 'invisible': Eval('street_unstructured') & ~Eval('private_bag'),
+ })
+ post_office = fields.Char(
+ "Post Office",
+ states={
+ 'invisible': Eval('street_unstructured') & ~Eval('post_office'),
+ })
+
street_single_line = fields.Function(
fields.Char("Street"),
'on_change_with_street_single_line',
@@ -79,6 +156,17 @@ class Address(
autocomplete_city=RPC(instantiate=0, cache=dict(days=1)),
)
+ @classmethod
+ def __register__(cls, module_name):
+ table = cls.__table_handler__(module_name)
+
+ # Migration from 7.4: rename street to street_unstructured
+ # and name to building_name
+ table.column_rename('street', 'street_unstructured')
+ table.column_rename('name', 'building_name')
+
+ super().__register__(module_name)
+
@fields.depends('street')
def on_change_with_street_single_line(self, name=None):
if self.street:
@@ -137,8 +225,7 @@ class Address(
AddressFormat = pool.get('party.address.format')
full_address = Template(AddressFormat.get_format(self)).substitute(
**self._get_address_substitutions())
- return '\n'.join(
- filter(None, (x.strip() for x in full_address.splitlines())))
+ return self._strip(full_address)
def _get_address_substitutions(self):
pool = Pool()
@@ -157,7 +244,6 @@ class Address(
substitutions = {
'party_name': '',
'attn': '',
- 'name': getattr(self, 'name', None) or '',
'street': getattr(self, 'street', None) or '',
'postal_code': getattr(self, 'postal_code', None) or '',
'city': getattr(self, 'city', None) or '',
@@ -179,8 +265,102 @@ class Address(
context['address_attention_party'].full_name)
for key, value in list(substitutions.items()):
substitutions[key.upper()] = value.upper()
+ substitutions.update(self._get_street_substitutions())
return substitutions
+ @fields.depends('street', 'street_unstructured')
+ def on_change_street(self):
+ self.street_unstructured = self.street
+
+ @fields.depends(
+ 'street_unstructured', 'country',
+ methods=['_get_street_substitutions'])
+ def on_change_with_street(self, name=None):
+ pool = Pool()
+ AddressFormat = pool.get('party.address.format')
+
+ format_ = AddressFormat.get_street_format(self)
+ street = Template(format_).substitute(
+ **self._get_street_substitutions())
+ if not (street := self._strip(street, doublespace=True)):
+ street = self.street_unstructured
+ return street
+
+ @classmethod
+ def set_street(cls, addresses, name, value):
+ addresses = [a for a in addresses if a.street != value]
+ cls.write(addresses, {
+ 'street_unstructured': value,
+ 'street_name': None,
+ 'building_name': None,
+ 'building_number': None,
+ 'unit_number': None,
+ 'floor_number': None,
+ 'room_number': None,
+ })
+
+ @classmethod
+ def search_street(cls, name, clause):
+ if clause[1].startswith('!') or clause[1].startswith('not '):
+ bool_op = 'AND'
+ else:
+ bool_op = 'OR'
+ return [bool_op,
+ ('street_unstructured', *clause[1:]),
+ ('street_name', *clause[1:]),
+ ('building_name', *clause[1:]),
+ ('building_number', *clause[1:]),
+ ('unit_number', *clause[1:]),
+ ('floor_number', *clause[1:]),
+ ('room_number', *clause[1:]),
+ ]
+
+ @fields.depends(
+ 'country', 'street_name', 'building_number', 'unit_number',
+ 'floor_number', 'room_number', 'post_box', 'private_bag',
+ 'post_office')
+ def _get_street_substitutions(self):
+ pool = Pool()
+ AddressFormat = pool.get('party.address.format')
+
+ substitutions = {
+ 'street_name': getattr(self, 'street_name', None) or '',
+ 'building_name': getattr(self, 'building_name', None) or '',
+ 'building_number': getattr(self, 'building_number', None) or '',
+ 'unit_number': getattr(self, 'unit_number', None) or '',
+ 'floor_number': getattr(self, 'floor_number', None) or '',
+ 'room_number': getattr(self, 'room_number', None) or '',
+ 'post_box': getattr(self, 'post_box', None) or '',
+ 'private_bag': getattr(self, 'private_bag', None) or '',
+ 'post_office': getattr(self, 'post_office', None) or '',
+ }
+ for number in [
+ 'building_number',
+ 'unit_number',
+ 'floor_number',
+ 'room_number',
+ 'post_box',
+ 'private_bag',
+ 'post_office',
+ ]:
+ if (substitutions[number]
+ and (format_ := AddressFormat.get_number_format(
+ number, self))):
+ substitutions[number] = format_.format(substitutions[number])
+ for key, value in list(substitutions.items()):
+ substitutions[key.upper()] = value.upper()
+ return substitutions
+
+ @classmethod
+ def _strip(cls, value, doublespace=False):
+ value = re.sub(
+ r'[\,\/,–][\s,\,\/]*([\,\/,–])', r'\1', value, flags=re.MULTILINE)
+ if doublespace:
+ value = re.sub(r' {1,}', r' ', value, flags=re.MULTILINE)
+ value = value.splitlines()
+ value = map(lambda x: x.strip(' ,/–'), value)
+ return '\n'.join(filter(None, value))
+
@property
def party_full_name(self):
name = ''
@@ -203,7 +383,6 @@ class Address(
return ', '.join(
filter(None, [
party,
- self.name,
street,
self.postal_code,
self.city,
@@ -217,7 +396,6 @@ class Address(
bool_op = 'OR'
return [bool_op,
('party',) + tuple(clause[1:]),
- ('name',) + tuple(clause[1:]),
('street',) + tuple(clause[1:]),
('postal_code',) + tuple(clause[1:]),
('city',) + tuple(clause[1:]),
@@ -267,9 +445,8 @@ class AddressFormat(DeactivableMixin, MatchMixin, ModelSQL, ModelView):
country_code = fields.Char("Country Code", size=2)
language_code = fields.Char("Language Code", size=2)
format_ = fields.Text("Format", required=True,
- help="Available variables (also in upper case):\n"
+ help="Available variables (also in upper case and street variables):\n"
"- ${party_name}\n"
- "- ${name}\n"
"- ${attn}\n"
"- ${street}\n"
"- ${postal_code}\n"
@@ -278,6 +455,39 @@ class AddressFormat(DeactivableMixin, MatchMixin, ModelSQL, ModelView):
"- ${subdivision_code}\n"
"- ${country}\n"
"- ${country_code}")
+ street_format = fields.Text("Street Format", required=True,
+ help="Available variables (also in upper case):\n"
+ "- ${street_name}\n"
+ "- ${building_name}\n"
+ "- ${building_number}\n"
+ "- ${unit_number}\n"
+ "- ${floor_number}\n"
+ "- ${room_number}\n"
+ "- ${post_box}\n"
+ "- ${private_bag}\n"
+ "- ${post_office}\n")
+ building_number_format = fields.Char(
+ "Building Number Format",
+ help="Use {} as placeholder for the number.")
+ unit_number_format = fields.Char(
+ "Unit Number Format",
+ help="Use {} as placeholder for the number.")
+ floor_number_format = fields.Char(
+ "Floor Number Format",
+ help="Use {} as placeholder for the number.")
+ room_number_format = fields.Char(
+ "Room Number Format",
+ help="Use {} as placeholder for the number.")
+
+ post_box_format = fields.Char(
+ "Post Box Format",
+ help="Use {} as placeholder for the number.")
+ private_bag_format = fields.Char(
+ "Post Box Format",
+ help="Use {} as placeholder for the number.")
+ post_office_format = fields.Char(
+ "Post Box Format",
+ help="Use {} as placeholder for the number.")
_get_format_cache = Cache('party.address.format.get_format')
@@ -291,7 +501,6 @@ class AddressFormat(DeactivableMixin, MatchMixin, ModelSQL, ModelView):
def default_format_(cls):
return """${attn}
${party_name}
-${name}
${street}
${postal_code} ${city}
${subdivision}
@@ -302,10 +511,19 @@ ${COUNTRY}"""
super().on_modification(mode, formats, field_names=field_names)
cls._get_format_cache.clear()
+ @classmethod
+ def default_street_format(cls):
+ return (
+ "${street_name} ${building_name} ${building_number}"
+ "/${unit_number}/${floor_number}/${room_number}\n"
+ "${post_box} ${private_bag} ${post_office}")
+
@classmethod
def validate_fields(cls, formats, field_names):
super().validate_fields(formats, field_names)
cls.check_format(formats, field_names)
+ cls.check_street_format(formats, field_names)
+ cls.check_number_format(formats, field_names)
@classmethod
def check_format(cls, formats, field_names=None):
@@ -323,8 +541,54 @@ ${COUNTRY}"""
format=format_.format_,
exception=exception)) from exception
+ @classmethod
+ def check_street_format(cls, formats, field_names=None):
+ pool = Pool()
+ Address = pool.get('party.address')
+ if field_names and 'street_format' not in field_names:
+ return
+ address = Address()
+ substitutions = address._get_street_substitutions()
+ for format_ in formats:
+ try:
+ Template(format_.street_format).substitute(**substitutions)
+ except Exception as exception:
+ raise InvalidFormat(gettext('party.msg_invalid_format',
+ format=format_.street_format,
+ exception=exception)) from exception
+
+ @classmethod
+ def check_number_format(cls, formats, field_names=None):
+ fields = [
+ 'building_number_format', 'floor_number_format',
+ 'unit_number_format', 'room_number_format',
+ 'post_box_format', 'private_bag_format', 'post_office_format']
+ if field_names and not (field_names & set(fields)):
+ return
+ for format_ in formats:
+ for field in fields:
+ if number_format := getattr(format_, field):
+ try:
+ number_format.format('')
+ except Exception as exception:
+ raise InvalidFormat(gettext('party.msg_invalid_format',
+ format=number_format,
+ exception=exception)) from exception
+
@classmethod
def get_format(cls, address, pattern=None):
+ return cls._get_format('format_', address, pattern=pattern)
+
+ @classmethod
+ def get_street_format(cls, address, pattern=None):
+ return cls._get_format('street_format', address, pattern=pattern)
+
+ @classmethod
+ def get_number_format(cls, number, address, pattern=None):
+ return cls._get_format(f'{number}_format', address, pattern=pattern)
+
+ @classmethod
+ def _get_format(cls, field, address, pattern=None):
if pattern is None:
pattern = {}
else:
@@ -333,17 +597,17 @@ ${COUNTRY}"""
'country_code', address.country.code if address.country else None)
pattern.setdefault('language_code', Transaction().language[:2])
- key = tuple(sorted(pattern.items()))
+ key = (field, *sorted(pattern.items()))
format_ = cls._get_format_cache.get(key)
if format_ is not None:
return format_
for record in cls.search([]):
if record.match(pattern):
- format_ = record.format_
+ format_ = getattr(record, field)
break
else:
- format_ = cls.default_format_()
+ format_ = getattr(cls, f'default_{field}', lambda: '')()
cls._get_format_cache.set(key, format_)
return format_
diff --git a/modules/party/address.xml b/modules/party/address.xml
index 4be7d7fb06..aa9868368a 100644
--- a/modules/party/address.xml
+++ b/modules/party/address.xml
@@ -147,85 +147,379 @@ this repository contains the full copyright notices and license terms. -->
-
+
+
+
+ AF
+ ${attn} ${party_name}
+${street}
+${city}
+${subdivision}
+${postal_code}
+${COUNTRY}
+ ${street_name}
+${building_number}
+ House No. {}
+
+
+
+ AD
+ ES
+ ${party_name}
+${attn}
+${STREET}
+${postal_code} ${CITY}
+${COUNTRY}
+ ${unit_number} ${floor_number} ${room_number}
+${building_name}
+${street_name} ${building_number}
+ AP {}
+
+
+
+ AD
+
+ ${party_name}
+${attn}
+${STREET}
+${POSTAL_CODE} ${CITY}
+${COUNTRY}
+ ${unit_number} ${floor_number} ${room_number}
+${building_name}
+${building_number} ${street_name}
+${post_box}
+ BP {}
+
+
+
+ AE
+ ${party_name}
+${street}
+${CITY}
+${COUNTRY}
+ ${post_box}
+ PO BOX {}
+
+
+
+ AI
+ ${party_name}
+${street}
+${city}
+${COUNTRY_CODE}-${postal_code}
+${COUNTRY}
+ ${unit_number}
+ P.O. {}
+
+
+
+ AL
+ ${party_name}
+${street}
+${postal_code}
+${city}
+${subdivision}
+${COUNTRY}
+ ${street_name}
+${building_number} ${floor_number} ${room_number}
+ Pallati {}
+ Shkalla {}
+ Apartamenti {}
+
+
+
+ AM
+ ${party_name}
+${street}
+${postal_code} ${CITY}
+${COUNTRY}
+ ${street_name} ${building_number} ${unit_number}
+ apt {}
+
+
+
+ AO
+ ${party_name}
+${street}
+${city}
+${COUNTRY}
+ ${street_name} ${building_number}–${floor_number}
+ {}o
+
+
AR
${party_name}
-${name}
+${attn}
${street}
-${subdivision}
${POSTAL_CODE}, ${city}
${COUNTRY}
-
-
-
- AU
- ${party_name}
-${attn}
-${name}
-${street}
-${CITY} ${SUBDIVISION} ${POSTAL_CODE}
-${COUNTRY}
+ ${street_name} ${building_number}
+${floor_number} ${room_number}
+${post_box}
+${post_office}
+ CASILLA DE CORREOS {}
AT
${party_name}
${attn}
-${name}
${street}
-${postal_code} ${city}
+${postal_code} ${CITY}
${COUNTRY}
+ ${street_name} ${building_number}/${unit_number}/${room_number}
+
+
+
+ AU
+ ${party_name}
+${attn}
+${street}
+${CITY} ${SUBDIVISION_CODE} ${POSTAL_CODE}
+${COUNTRY}
+ ${building_name}
+${room_number}/${floor_number}/${unit_number}/${building_number} ${street_name}
+${post_box}
+ PO BOX {}
+
+
+
+ AW
+ ${party_name}
+${street}
+${city}
+${COUNTRY}
+ ${building_name}
+${street_name} ${building_number}
+ #{}
+
+
+
+ AZ
+ ${party_name}
+${street}
+${COUNTRY_CODE}${postal_code} ${city}
+${subdivision}
+${COUNTRY}
+ ${street_name} ${building_number}
+${post_box}
+ a/q {}
+
+
+
+ BA
+ ${party_name}
+${street}
+${postal_code} ${CITY}
+${COUNTRY}
+ ${building_name}
+${street_name} ${building_number}
+
+
+
+ BB
+ ${party_name}
+${street}
+${city} ${COUNTRY_CODE}${postal_code}
+${COUNTRY}
+ ${building_number}
+${street_name}
+${building_name}
+ #{}
BD
${party_name}
-${attn}
-${name}
${street}
-${city}-${postal_code}
-${COUNTRY}
-
-
-
- BY
- ${party_name}
-${name}
-${street}
-${postal_code}, ${city}
-${subdivision}
+${CITY} - ${postal_code}
${COUNTRY}
+ ${unit_number}/${floor_number}/${room_number} ${building_name}
+${street_name} ${building_number}
BE
${attn}
${party_name}
-${name}
${street}
${postal_code} ${city}
${COUNTRY}
+ ${building_name}
+${street_name} ${building_number} ${unit_number}
+${post_box}
+ box {}
+ bpack {}
-
- BR
+
+ BF
${party_name}
${street}
-${name}
-${city} - ${subdivision_code}
-${postal_code}
+${postal_code} ${CITY}
${COUNTRY}
+ ${building_name}
+${building_number} ${street_name}
+${post_box} ${post_office}
+ BP {}
BG
${party_name}
${street}
-${name}
-${postal_code} ${city}
+${postal_code} ${CITY}
+${SUBDIVISION}
+${COUNTRY}
+ ${street_name} ${building_number}, ${unit_number}, ${floor_number}, ${room_number}
+${building_name}
+ No. {}
+ бл. {}
+ ет. {}
+ ап. {}
+
+
+
+ BH
+ ${party_name}
+${street}
+${CITY} ${postal_code}
+${COUNTRY}
+ ${building_number}
+${street_name}
+${post_box}
+ House {}
+ P.O Box {}
+
+
+
+ BI
+ ${party_name}
+${street}
+${CITY}
+${COUNTRY}
+ ${post_box}
+ BP {}
+
+
+
+ BJ
+ ${party_name}
+${street}
+${CITY}
+${COUNTRY}
+ ${building_number} ${street_name}
+
+
+
+ BM
+ ${party_name}
+${street}
+${CITY} ${POSTAL_CODE}
+${COUNTRY}
+ ${building_number}
+${unit_number}
+${building_number} ${street_name}
+${post_box}
+ PO Box {}
+
+
+
+ BN
+ ${PARTY_NAME}
+${STREET}
+${CITY}
+${SUBDIVISION} ${POSTAL_CODE}
+${COUNTRY}
+ ${building_number}, ${floor_number}, ${street_name}
+
+
+
+ BO
+ ${attn}
+${party_name}
+${street}
+${CITY}
+BOLIVIA
+ ${STREET_NAME} ${BUILDING_NUMBER}
+${building_name}
+${post_box}
+ Casilla Postal {}
+
+
+
+ BR
+ ${party_name}
+${street}
+${CITY} - ${SUBDIVISION_CODE}
+${postal_code}
+${COUNTRY}
+ ${street_name}, ${building_number}, ${unit_number}/${floor_number}/${room_number}
+${building_name}
+
+
+
+ BS
+ ${party_name}
+${street}
+${city}
+${COUNTRY}
+ ${post_office} ${post_box}
+ P.O. Box {}
+
+
+
+ BT
+ ${party_name}
+${street}
+${city} ${postal_code}
+${COUNTRY}
+ ${street_name}, ${building_number}
+${unit_number}
+${room_number}
+${building_name}
+${post_box}
+${post_office}
+ House No. {}
+ Flat No. {}
+ P.O Box {}
+
+
+
+ BW
+ ${party_name}
+${street}
+${CITY}
+${COUNTRY}
+ ${post_box}
+${private_bag}
+ P.O. Box {}
+ P/Bag {}
+
+
+
+ BY
+ ${party_name}
+${street}
+${postal_code}, ${city}
${subdivision}
${COUNTRY}
+ ${street_name}, ${building_number}, ${unit_number}, ${floor_number}, ${room_number}
+ d. {}
+ bud. {}
+ kv. {}
+
+
+
+ BZ
+ ${party_name}
+${street}
+${CITY}
+${COUNTRY}
+ ${building_number} ${street_name} ${room_number}
+ Apt {}
@@ -233,53 +527,194 @@ ${COUNTRY}
fr
${attn}
${party_name}
-${name}
${street}
${city} (${subdivision}) ${postal_code}
${COUNTRY}
+ ${building_name}
+${unit_number}–${building_number}, ${street_name}
CA
${ATTN}
${PARTY_NAME}
-${NAME}
${STREET}
${CITY} ${SUBDIVISION_CODE} ${POSTAL_CODE}
${COUNTRY}
+ ${building_name}
+${unit_number}–${building_number} ${street_name}
+${post_box} ${post_office}
+ PO BOX {}
+
+
+
+ CD
+ ${party_name}
+${street}
+${CITY}
+${postal_code} ${SUBDIVISION}
+CONGO (REP.)
+ ${street_name} ${building_number}
+${post_box}
+ N°{}
+ B.P {}
+
+
+
+ CF
+ ${attn}
+${party_name}
+${street}
+${CITY}
+${COUNTRY}
+ ${post_box}
+ BP {}
+
+
+
+ CG
+ ${party_name}
+${street}
+${CITY}
+${COUNTRY}
+ ${building_number}, ${street_name}
+
+
+
+ CH
+ ${party_name}
+${street}
+${postal_code} ${CITY}
+${COUNTRY}
+ ${street_name} ${building_number}
+${post_box}
+ Case postale {}
+
+
+
+ CI
+ ${attn}
+${party_name}
+${street_name}
+${post_office} ${street} ${CITY} ${post_office}
+${COUNTRY}
+ ${post_box}
+ B.P. {}
+
+
+
+ CK
+ ${party_name}
+${street}, ${city}
+${SUBDIVISION}
+${COUNTRY}
+ ${post_box}
+${street_name}
+ PO Box {}
CL
+ ${attn}
+${party_name}
+${street}
+${postal_code} ${CITY}
+${SUBDIVISION}
+${COUNTRY}
+ ${street_name} ${building_number}, ${unit_number}, ${floor_number}, ${room_number}
+${building_name}
+ N° {}
+ Dep. {}
+ Piso {}
+
+
+
+ CM
${party_name}
${street}
-${name}
-${postal_code}
-${city}
+${CITY}
${COUNTRY}
+ ${post_box}
+ BP {}
CN
zh
${COUNTRY} ${POSTAL_CODE}
-${subdivision}${city}${street}${name}
+${subdivision}${city}${street}
${party_name}
+ ${building_number}${unit_number}${floor_number}${room_number}${building_name}
CN
- ${COUNTRY} ${POSTAL_CODE}
-${subdivision}, ${city}, ${street}, ${name}
-${party_name}
-
-
-
- HR
${party_name}
${street}
-${COUNTRY_CODE}-${POSTAL_CODE} ${city}
+${city}
+${postal_code} ${SUBDIVISION}
${COUNTRY}
+ ${room_number}, ${floor_number}, ${unit_number}
+${building_number}, ${street_name}
+ Room {}
+ Floor {}
+ Building {}
+ No. {}
+
+
+
+ CO
+ ${party_name}
+${street}
+${CITY} ${postal_code}
+${COUNTRY}
+ ${building_name}
+${street_name} ${building_number} ${unit_number}
+
+
+
+ CR
+ ${party_name}
+${street}
+${subdivision}
+${post_box}-${postal_code}
+${COUNTRY}
+ ${street_name} ${building_number}
+${post_office}-${post_box}
+ # {}
+ Apdo {}
+
+
+
+ CU
+ ${party_name}
+${street}
+${city}
+${POSTAL_CODE} ${SUBDIVISION}
+${COUNTRY}
+
+
+
+ CV
+ ${party_name}
+${street}
+${postal_code} ${CITY}
+${SUBDIVISION}
+${COUNTRY}
+ ${street_name} ${building_number}
+${post_box}
+ C.P. {}
+
+
+
+ CY
+ ${party_name}
+${street}
+${COUNTRY_CODE}-${postal_code} ${city}
+${COUNTRY}
+ ${street_name} ${building_number}
+${post_box}
+ P.O. Box {}
@@ -287,24 +722,149 @@ ${COUNTRY}
${party_name}
${attn}
${street}
-${COUNTRY_CODE}-${POSTAL_CODE} ${city}
+${postal_code} ${CITY} ${POST_OFFICE}
${COUNTRY}
+ ${street_name} ${building_number}
+${post_box}
+ poštovní přihrádka {}
+
+
+
+ DE
+ ${party_name}
+${attn}
+${street}
+${postal_code} ${city}
+${COUNTRY}
+ ${street_name} ${building_number} // ${unit_number}
+${post_box}
+ Appartement {}
+ Postfach {}
+
+
+
+ DJ
+ ${party_name}
+${street}
+${postal_code} ${CITY}
+${COUNTRY}
+ ${post_box}
+ BP {}
DK
${party_name}
${street}
+${postal_code} ${CITY}
+${COUNTRY}
+ ${street_name} ${building_number}, ${floor_number}
+${post_box}
+ Postboks {}
+
+
+
+ DM
+ ${party_name}
+${street}
+${CITY}
+${COUNTRY}
+ ${street_name}
+
+
+
+ DO
+ ${party_name}
+${street}
+${postal_code} ${CITY}
+${COUNTRY}
+ ${street_name} ${building_number}
+${building_name}
+ # {}
+
+
+
+ DZ
+ ${party_name}
+${street}
${postal_code} ${city}
${COUNTRY}
+ ${building_number}, ${street_name}
+
+
+
+ EC
+ ${party_name}
+${street}
+${postal_code} - ${CITY}
+${COUNTRY}
+ ${street_name} ${building_number}
+${building_name}, ${floor_number}
+ piso {}
EE
${party_name}
${street}
-${postal_code} ${city}
+${postal_code} ${CITY}
${COUNTRY}
+ ${building_name}
+${street_name} ${building_number}–${unit_number}
+
+
+
+ EG
+ ${party_name}
+${street}
+${city}
+${subdivision}
+${postal_code}
+${COUNTRY}
+ ${building_number} ${street_name} - ${building_name}
+${post_box}
+${post_office}
+ P. O. Box {}
+ {} post office
+
+
+
+ ER
+ ${party_name}
+${street}
+${CITY}
+${COUNTRY}
+ ${street_name} ${building_number}
+
+
+
+ ES
+ ${party_name}
+${street}
+${postal_code} ${CITY}
+${SUBDIVISION}
+${COUNTRY}
+ ${building_name}
+${street_name}, ${building_number}, ${floor_number}, ${room_number}
+${post_box}
+ Apartado {}
+
+
+
+ ES
+
+
+
+
+ ET
+ ${party_name}
+${street}
+${postal_code} ${CITY}
+${COUNTRY}
+ ${street_name} ${building_number}
+${post_box}
+ house no {}
+ P.O. Box {}
@@ -312,83 +872,373 @@ ${COUNTRY}
${attn}
${party_name}
${street}
-${postal_code} ${city}
+${postal_code} ${CITY}
${COUNTRY}
+ ${street_name} ${building_number} ${unit_number}
+ as {}
+
+
+
+ FJ
+ ${party_name}
+${STREET}
+${CITY}
+${COUNTRY}
+ ${building_number} ${street_name}
+
+
+
+ FK
+ ${party_name}
+${street}
+${CITY}
+${POSTAL_CODE}
+${COUNTRY}
+ ${building_number} ${street_name}
+
+
+
+ FM
+
+ ${attn}
+${party_name}
+${street}
+${CITY} ${SUBDIVISION_CODE} ${postal_code}
+MICRONESIA (FEDERATED STATES OF)
+ ${building_name}
+${building_number} ${street_name} ${unit_number}
+${post_box}
+ PO Box {}
FR
${party_name}
${attn}
-${name}
+${STREET}
+${POSTAL_CODE} ${CITY}
+${COUNTRY}
+ ${unit_number} ${floor_number} ${room_number}
+${building_name}
+${building_number} ${street_name}
+${post_box}
+ BP {}
+
+
+
+ GA
+ ${party_name}
+${STREET}
+${postal_code} ${CITY} ${POST_OFFICE}
+${COUNTRY}
+ ${street_name}
+${post_box}
+ BP {}
+
+
+
+ GB
+ ${attn}
+${party_name}
${street}
+${CITY}
+${POSTAL_CODE}
+${COUNTRY}
+ ${building_name}
+${building_number} ${street_name}
+
+
+
+ GD
+ ${party_name}
+${street}
+${city}
+${SUBDIVISION}
+${COUNTRY}
+ ${post_box}
+ P.O. BOX {}
+
+
+
+ GE
+ ${party_name}
+${street}
+${postal_code} ${CITY}
+${COUNTRY}
+ ${street_name} ${building_number}, ${unit_number}
+ #{}
+ flat {}
+
+
+
+ GF
+
+ ${party_name}
+${attn}
+${STREET}
+${POSTAL_CODE} ${CITY}
+FRANCE
+ ${unit_number} ${floor_number} ${room_number}
+${building_name}
+${building_number} ${street_name}
+${post_box}
+ BP {}
+
+
+
+ GH
+ ${party_name}
+${street}
+${city} ${postal_code}
+${SUBDIVISION}
+${COUNTRY}
+ ${building_name}
+${building_number} ${street_name}
+ No. {}
+
+
+
+ GI
+ ${party_name}
+${street}
+${city}
+${postal_code}
+${COUNTRY}
+ ${building_name}
+${building_number} ${street_name}
+${post_box}
+ PO Box {}
+
+
+
+ GM
+ ${party_name}
+${street}
+${CITY}
+${COUNTRY}
+ ${building_number} ${street_name}
+
+
+
+ GN
+ ${party_name}
${POSTAL_CODE} ${CITY}
${COUNTRY}
-
- DE
+
+ GP
+
${party_name}
${attn}
-${name}
-${street}
-${postal_code} ${city}
-${COUNTRY}
+${STREET}
+${POSTAL_CODE} ${CITY}
+FRANCE
+ ${unit_number} ${floor_number} ${room_number}
+${building_name}
+${building_number} ${street_name}
+${post_box}
+ BP {}
GR
${party_name}
-${street}
+${STREET}
${COUNTRY_CODE}-${POSTAL_CODE} ${CITY}
${COUNTRY}
+ ${building_number}, ${street_name}
+${post_box}
+ P.O. BOX {}
+
+
+
+ GS
+ ${party_name}
+${street}
+${CITY}
+${POSTAL_CODE}
+SOUTH GEORGIA ISLAND
+
+
+
+ GT
+ ${party_name}
+${street}
+${postal_code} - ${city}
+${COUNTRY}, ${SUBDIVISION_CODE}
+ ${street_name} {building_number}
+${unit_number} ${floor_number} ${room_number}
+
+
+
+ GQ
+ ${attn}
+${party_name}
+${street}
+${SUBDIVISION}, ${CITY}
+${COUNTRY}
+ ${street_name}
+${post_box}
+ Apartado postal {}
+
+
+
+ GW
+ ${party_name}
+${street}
+${postal_code} ${CITY}
+${COUNTRY}
+ ${street_name} ${building_number}
+
+
+
+ HK
+ zh
+ ${COUNTRY}
+${subdivision}
+${street}
+${party_name}
+ ${building_number}${building_number}
+${building_name}${floor_number}${unit_number}
HK
${party_name}
-${name}
+${room_number}, ${floor_number}
${street}
-${subdivision}
+${CITY}
${COUNTRY}
+ ${building_name}
+${building_number} ${street_name}
+${post_box}
+${POST_OFFICE}
+ Flat {}
+ P.O. Box {}
+
+
+
+ HN
+ ${party_name}
+${street}
+${POSTAL_CODE} ${CITY}, ${SUBDIVISION}
+${COUNTRY}
+
+
+
+ HR
+ ${party_name}
+${street}
+${COUNTRY_CODE}-${POSTAL_CODE} ${CITY}
+${COUNTRY}
+ ${street_name} ${building_number} ${floor_number} ${room_number}
+${post_box}
+ {} kat
+ stan {}
+ P.P. {}
+
+
+
+ HT
+ ${party_name}
+${street}
+${COUNTRY_CODE}${postal_code} ${CITY}
+${COUNTRY}
+ ${street_name} ${building_number}
HU
${party_name}
-${city}
-${street}
+${CITY}
+${STREET}
${postal_code}
${COUNTRY}
+ ${street_name} ${building_number} ${unit_number} ${floor_number}/${room_number}
+${post_box}
+ hrsz {}
+ fszt {}
+ PF. {}
+
+
+
+ IE
+ ${party_name}
+${street}
+${CITY}
+${POSTAL_CODE}
+${COUNTRY}
+ ${building_name} ${building_number} ${street_name}
+
+
+
+ IL
+ ${party_name}
+${street}
+${postal_code} ${CITY}
+${COUNTRY}
+ ${building_number}/${unit_number} ${street_name}
+
+
+
+ IN
+ ${party_name}
+${street}
+${city}
+${subdivision}
+${postal_code}
+${COUNTRY}
+ ${unit_number}, ${building_name}
+${building_number}, ${street_name}
IS
${party_name}
${street}
-${name}
-${postal_code} ${city}
+${postal_code} ${CITY}
${COUNTRY}
+ ${street_name} ${building_number}
+${post_box}
+ íbúð {}
+ Pósthólf {}
-
- IN
- ${party_name}
-${name}
-${street}
-${CITY} ${postal_code}
-${subdivision}
+
+ IT
+ ${PARTY_NAME}
+${ATTN}
+${STREET}
+${POSTAL_CODE} ${CITY} ${SUBDIVISION_CODE}
${COUNTRY}
+ ${building_name}
+${unit_number} ${floor_number} ${room_number}
+${street_name} ${building_number}
+${post_office}
+${post_box}
+ CASELLA POSTALE {}
+
+ IT
+
+
+
+
ID
${party_name}
-${name}
${street}
-${city} ${postal_code}
-${subdivision}
+${CITY} ${postal_code}
+${SUBDIVISION}
${COUNTRY}
+ ${building_name} ${room_number}
+${street_name} ${building_number} ${unit_number}
+${POST_BOX}
+${POST_OFFICE}
+ No. {}
+ PO BOX {}
@@ -399,53 +1249,51 @@ ${COUNTRY}
IR
${party_name}
-${name}
${city}
${street}
${subdivision}
${postal_code}
-${COUNTRY}
+IRAN (ISLAMIC REP.)
+ ${street_name}
+${building_number}/${unit_number}/${floor_number}/${room_number}
+${building_name}
IQ
${party_name}
${street}
-${name}
-${subdivision}
+${SUBDIVISION}
${postal_code}
${COUNTRY}
+ ${building_number} ${street_name}
+${post_box}
+ P.O. box {}
-
- IE
+
+ JM
${party_name}
${street}
-${city} ${postal_code}
+${city}
+${subdivision}
${COUNTRY}
+ ${building_name}
+${building_number} ${street_name}
+${post_box}
+${post_office}
+ P.O. Box {}
-
- IL
+
+ JO
${party_name}
${street}
-${city} ${postal_code}
+${CITY} ${postal_code}
${COUNTRY}
-
-
-
- IT
- ${party_name}
-${attn}
-${name}
-${street}
-${postal_code} ${city} ${SUBDIVISION_CODE}
-${COUNTRY}
-
-
-
- IT
-
+ ${building_name}
+${street_name}
+${building_number}–${unit_number}
@@ -455,23 +1303,95 @@ ${COUNTRY}
${postal_code}
${subdivision}${city}${street}
${party_name}
+ ${street_name}${building_number}${building_name}${floor_number}
JP
${party_name}
${street}
-${city}, ${SUBDIVISION} ${postal_code}
+${city}, ${SUBDIVISION}
+${postal_code}
${COUNTRY}
+ ${floor_number}–${building_name}–${building_number}, ${street_name}
+
+
+
+ KE
+ ${party_name}
+${street}
+${postal_code}
+${CITY}
+${COUNTRY}
+ ${post_box} – ${post_office}
+ P O BOX {}
+
+
+
+ KG
+ ${party_name}
+${street}
+${postal_code} ${CITY}
+${SUBDIVISION}
+${COUNTRY}
+ ${building_number}, ${street_name}, ${unit_number}
+${post_box}
+${post_office}
+ PO-{}
+
+
+
+ KH
+ ${party_name}
+${street}
+${city}
+${SUBDIVISION} ${postal_code}
+${COUNTRY}
+ ${building_number} ${street_name}
+
+
+
+ KI
+ ${party_name}
+${street}
+${city}
+${subdivision} ${postal_code}
+${COUNTRY}
+ ${post_box}
+${post_office}
+ PO Box {}
+
+
+
+ KM
+ ${party_name}
+${street}
+${CITY}
+${COUNTRY}
+ ${post_box}
+ BP {}
+
+
+
+ KN
+ ${party_name}
+${street}
+${city}
+${subdivision}
+${postal_code}
+ST. KITTS AND NEVIS
+ ${building_number} ${street_name}
KR
ko
- ${COUNTRY}
+ REP. OF KOREA
${street}
${party_name}
${postal_code}
+ ${street_name} ${building_number}/${unit_number}/${floor_number}/${room_number}
+${post_box}
@@ -479,217 +1399,95 @@ ${postal_code}
${party_name}
${street}
${city}, ${subdivision} ${postal_code}
-${COUNTRY}
+REP. OF KOREA
+ ${street_name} ${building_number}/${unit_number}/${floor_number}/${room_number}
+${post_box}
+ P.O. Box {}
-
- LV
+
+ KW
${party_name}
${street}
-${city}
-${subdivision}
-${COUNTRY_CODE}-${POSTAL_CODE}
-${COUNTRY}
-
-
-
- MO
- zh
- ${COUNTRY}
-${city}
-${street}
-${party_name}
-
-
-
- MO
- ${party_name}
-${street}
-${city}
-${COUNTRY}
-
-
-
- MY
- ${attn}
-${party_name}
-${name}
-${street}
${postal_code} ${CITY}
-${SUBDIVISION}
${COUNTRY}
+ ${unit_number}, ${street_name}, ${building_number}
+ Parcelle {}
+ immeuble {}
-
- MX
+
+ KY
${attn}
${party_name}
${street}
-${name}
-${postal_code}, ${city}, ${subdivision}
+${subdivision} ${COUNTRY_CODE}${postal_code}
${COUNTRY}
+ ${post_box}
+${post_office}
+ P.O. Box {}
-
- NL
- ${party_name}
-${attn}
-${name}
-${street}
-${postal_code} ${CITY}
-${COUNTRY}
-
-
-
- NZ
- ${party_name}
-${street}
-${city} ${postal_code}
-${COUNTRY}
-
-
-
- NO
- ${party_name}
-${street}
-${postal_code} ${CITY}
-${COUNTRY}
-
-
-
- OM
- ${party_name}
-${street}
-${city}
-${COUNTRY}
-
-
-
- PK
- ${party_name}
-${street}
-${city}
-${postal_code}
-${subdivision}
-${COUNTRY}
-
-
-
- PE
- ${party_name}
-${street}
-${name}
-${city}
-${subdivision}
-${COUNTRY}
-
-
-
- PH
- ${party_name}
-${street}
-${postal_code} ${CITY}
-${COUNTRY}
-
-
-
- PL
- ${attn} ${party_name}
-${street}
-${postal_code} ${city}
-${COUNTRY}
-
-
-
- PT
- ${party_name}
-${street}
-${postal_code} ${city}
-${COUNTRY}
-
-
-
- QA
- ${party_name}
-${street}
-${city}
-${COUNTRY}
-
-
-
- RO
- ${attn} ${party_name}
-${street}
-${city}
-${postal_code}
-${COUNTRY}
-
-
-
- RU
- ${party_name}
-${street}
-${city}
-${subdivision}
-${COUNTRY}
-${postal_code}
-
-
-
- SA
- ${party_name}
-${street}
-${city} ${postal_code}
-${COUNTRY}
-
-
-
- RS
- ${party_name}
-${street}
-${postal_code} ${city}
-${COUNTRY}
-
-
-
- SG
- ${party_name}
-${street}
-${name}
-${CITY} ${POSTAL_CODE}
-${COUNTRY}
-
-
-
- SK
+
+ KZ
${attn}
${party_name}
${street}
-${postal_code} ${city}
+${POSTAL_CODE} ${CITY}
${COUNTRY}
+ ${street_name}, ${building_number}, {unit_number}
+${post_box}
+ dom {}
+ kv {}
+ a/ya {}
-
- SL
- ${party_name}
-${attn}
-${street}
-${postal_code} ${city}
-${COUNTRY}
-
-
-
- ES
+
+ LA
${party_name}
${street}
-${postal_code} ${city}
-${subdivision}
-${COUNTRY}
+${postal_code} ${CITY}
+LAO (PEOPLE'S DEM. REP.)
+ ${building_number}, ${street_name}
-
- ES
-
+
+ LB
+ ${attn}
+${party_name}
+${street}
+${CITY} ${SUBDIVISION}
+${COUNTRY}
+ ${building_number}, ${floor_number}, ${room_number}
+${street_name}
+${post_box}
+ P.O. Box {}
+
+
+
+ LC
+ ${attn}
+${party_name}
+${street}
+${SUBDIVISION}, ${POSTAL_CODE}
+${COUNTRY}
+ ${unit_number}, ${building_number}
+${street_name}
+${post_box}
+${post_office}
+ P.O Box {}
+
+
+
+ LI
+
+ ${party_name}
+${street}
+${postal_code} ${CITY}
+${COUNTRY}
+ ${street_name} ${building_number}
+${post_box}
+ Case postale {}
@@ -699,31 +1497,1085 @@ ${street}
${CITY}
${postal_code}
${COUNTRY}
+ ${building_number} ${street_name}
+
+
+
+ LR
+ ${party_name}
+${street}
+${postal_code} ${city}
+${COUNTRY}
+ ${street_name}
+${post_box}
+ P O Box {}
+
+
+
+ LS
+ ${party_name}
+${street}
+${CITY} ${postal_code}
+${COUNTRY}
+ ${post_box}
+ P.O. Box {}
+
+
+
+ LT
+ ${party_name}
+${street}
+${city}
+${COUNTRY_CODE}–${postal_code} ${SUBDIVISION}
+${COUNTRY}
+ ${street_name} ${building_number}-${unit_number}
+${post_box}
+${post_office}
+ P. d. {}
+
+
+
+ LU
+ ${attn}
+${party_name}
+${unit_number}
+${street}
+L-${postal_code} ${CITY}
+${COUNTRY}
+ ${private_bag}
+${building_number}, ${street_name}
+${post_box}
+ BP {}
+
+
+
+ LV
+ ${party_name}
+${street}
+${city}, ${COUNTRY_CODE}-${POSTAL_CODE}
+${COUNTRY}
+ ${street_name} ${building_number}–${unit_number}
+
+
+
+ LY
+ ${party_name}
+${street}
+${CITY}
+${COUNTRY}
+ ${street_name} ${building_number}
+
+
+
+ MA
+ ${PARTY_NAME}
+${UNIT_NUMBER}
+${STREET}
+${POSTAL_CODE} ${CITY}
+${COUNTRY}
+ ${building_name}
+${building_number} ${street_name}
+${post_box}
+${post_office}
+ APARTMENT N° {}
+ P.O {}
+
+
+
+ MC
+
+ ${party_name}
+${attn}
+${STREET}
+${POSTAL_CODE} ${CITY}
+${COUNTRY}
+ ${unit_number} ${floor_number} ${room_number}
+${building_name}
+${building_number} ${street_name}
+${post_box}
+ BP {}
+
+
+
+ MD
+ ${party_name}
+${street}
+${POSTAL_CODE}, ${CITY}
+MOLDOVA
+ ${street_name}, ${building_number}, ${unit_number}
+${post_box}
+${post_office}
+ nr. {}
+ ap. {}
+ Căsuţa poştăla {}
+
+
+
+ ME
+ ${party_name}
+${street}
+${postal_code} ${CITY}
+${COUNTRY}
+ ${street_name} ${building_number} / ${unit_number}
+${post_box}
+${post_office}
+ PP {}
+
+
+
+ MG
+ ${attn}
+${party_name}
+${street}
+${postal_code} ${CITY}
+${COUNTRY}
+ ${unit_number} ${building_number} ${building_name}
+${post_box}
+ B.P. {}
+
+
+
+ MH
+
+ ${attn}
+${party_name}
+${street}
+${CITY} ${SUBDIVISION_CODE} ${postal_code}
+${COUNTRY}
+ ${building_name}
+${building_number} ${street_name} ${unit_number}
+${post_box}
+ PO Box {}
+
+
+
+ MK
+ ${party_name}
+${street}
+${postal_code} ${city}
+${COUNTRY}
+ ${street_name} ${building_number}
+${post_box}
+ P. fah {}
+
+
+
+ ML
+ ${attn}
+${party_name}
+${street}
+${CITY}
+${COUNTRY}
+ ${street_name} – ${building_number}
+ Porte {}
+
+
+
+ MM
+ ${attn}
+${party_name}
+${street}
+${CITY} ${POST_OFFICE}, ${postal_code}
+${subdivision}
+${COUNTRY}
+ ${building_number}, ${street_name}
+${post_box}
+ No. {}
+ P.O Box ({})
+
+
+
+ MN
+ ${party_name}
+${street}
+${city}
+${SUBDIVISION} ${postal_code}
+${COUNTRY}
+ ${street_name} ${building_number}
+${post_box} ${post_office}
+ PO.Box {}
+ PO {}
+
+
+
+ MO
+ zh
+ ${COUNTRY}
+${city}
+${street}
+${party_name}
+ ${street_name} ${building_number}
+${building_name}${floor_number}${room_number}
+${post_box}
+${post_office}
+ P.O. Box {}
+
+
+
+ MO
+ ${party_name}
+${street}
+${city}
+${COUNTRY}
+ ${street_name}, ${building_number}, ${building_name}, ${floor_number}, ${room_number}
+${post_box}
+${post_office}
+ n.o {}
+ {} andar
+ moradia {}
+ P.O. Box {}
+
+
+
+ MQ
+
+ ${party_name}
+${attn}
+${STREET}
+${POSTAL_CODE} ${CITY}
+${COUNTRY}
+ ${unit_number} ${floor_number} ${room_number}
+${building_name}
+${building_number} ${street_name}
+${post_box}
+ BP {}
+
+
+
+ MR
+ ${party_name}
+${street}
+${CITY}
+${COUNTRY}
+ ${post_box}
+ B.P. {}
+
+
+
+ MS
+ ${party_name}
+${street}
+${city}, ${POSTAL_CODE}
+${COUNTRY}
+ ${street_name}
+${post_box}
+ PO Box {}
+
+
+
+ MT
+ ${party_name}
+${street}
+${CITY}
+${POSTAL_CODE}
+${COUNTRY}
+ ${building_number} ${street_name}
+${post_box}
+ Kaxxa Postali {}
+
+
+
+ MU
+ ${attn}
+${party_name}
+${street}
+${city} ${postal_code}
+${COUNTRY}
+ ${building_number}, ${street_name}
+
+
+
+ MV
+ ${party_name}
+${STREET}
+${CITY} ${postal_code}
+${COUNTRY}
+ ${building_number}, ${street_name}
+
+
+
+ MW
+ ${attn}
+${party_name}
+${street}
+${city}
+${postal_code} ${SUBDIVISION}
+${COUNTRY}
+ ${building_name}
+${building_number} ${street_name}
+${post_box}
+ P. O. Box {}
+
+
+
+ MX
+ ${attn}
+${party_name}
+${street}
+${postal_code} ${CITY}, ${SUBDIVISION_CODE}
+${COUNTRY}
+ ${street_name} ${building_number} ${unit_number} ${floor_number} ${room_number}
+${building_name}
+
+
+
+ MY
+ ${attn}
+${party_name}
+${street}
+${postal_code} ${CITY}
+${SUBDIVISION}
+${COUNTRY}
+ ${unit_number}, ${floor_number}, ${room_number}, ${building_name}
+${building_number}, ${street_name}
+${post_box}
+ Peti surat {}
+
+
+
+ MZ
+ ${party_name}
+${street}
+${postal_code} ${CITY}
+${SUBDIVISION}
+${COUNTRY}
+ ${street_name}
+${building_number}, ${floor_number}, ${room_number}
+${post_box}
+ P.O Box {}
+
+
+
+ NA
+ ${attn}
+${party_name}
+${street}
+${CITY}
+${postal_code}
+${COUNTRY}
+ ${building_name}
+${building_number}/${unit_number} ${street_name}
+${post_box}
+${POST_OFFICE}
+ PO Box {}
+
+
+
+ NC
+ ${party_name}
+${unit_number}
+${street}
+${postal_code} ${CITY}
+${COUNTRY}
+ ${building_name}
+${building_number} ${street_name}
+${post_box}
+ APPARTEMENT {}
+ BP {}
+
+
+
+ NE
+ ${party_name}
+${street}
+${postal_code} ${CITY}
+${COUNTRY}
+ ${post_box}
+ BP {}
+
+
+
+ NF
+
+ ${party_name}
+${attn}
+${street}
+${CITY} ${SUBDIVISION_CODE} ${POSTAL_CODE}
+${COUNTRY}
+ ${building_name}
+${room_number}/${floor_number}/${unit_number}/${building_number} ${street_name}
+${post_box}
+ PO BOX {}
+
+
+
+ NG
+ ${attn}
+${party_name}
+${street}
+${city} ${postal_code}
+${SUBDIVISION}
+${COUNTRY}
+ ${building_number} ${street_name}
+${post_box}
+ P.O.Box. {}
+
+
+
+ NI
+ ${party_name}
+${street}
+${postal_code}
+${city}, ${subdivision}
+${COUNTRY}
+ ${street_name}, ${building_number}
+
+
+
+ NL
+ ${party_name}
+${attn}
+${street}
+${POSTAL_CODE} ${CITY}
+${COUNTRY}
+ ${building_name}
+${street_name} ${building_number}
+${post_box}
+ Postbus {}
+
+
+
+ NO
+ ${party_name}
+${attn}
+${street}
+${postal_code} ${CITY}
+${COUNTRY}
+ ${building_name}
+${street_name} ${building_number}
+${post_box} ${post_office}
+ Postboks {}
+
+
+
+ NP
+ ${party_name}
+${street}
+${CITY} ${postal_code}
+${COUNTRY}
+ ${building_number}, ${street_name}
+${building_name}
+
+
+
+ NR
+ ${party_name}
+${STREET}
+${SUBDIVISION}
+${POSTAL_CODE}
+${COUNTRY}
+ ${building_name}
+
+
+
+ NZ
+ ${attn}
+${party_name}
+${street}
+${CITY} ${postal_code}
+${COUNTRY}
+ ${unit_number}/${building_number} ${street_name}
+${building_name}
+ PO Box {}
+
+
+
+ OM
+ ${party_name}
+${street}
+${postal_code}
+${CITY}
+${COUNTRY}
+ ${building_number} ${street_name}
+ BP {}
+
+
+
+ PA
+ ${ATTN}
+${PARTY_NAME}
+${STREET}
+${CITY}
+${SUBDIVISION}
+${COUNTRY}
+ ${street_name} ${building_number}
+${building_name}
+${post_box}
+${post_office}
+${private_bag}
+ APARTADO POSTAL {}
+ Private Bag {}
+
+
+
+ PE
+ ${party_name}
+${street}, ${city}
+${postal_code}
+${SUBDIVISION}
+${COUNTRY}
+ ${street_name} ${building_number}
+
+
+
+ PF
+
+ ${party_name}
+${attn}
+${STREET}
+${POSTAL_CODE} ${CITY} ${SUBDIVISION}
+${COUNTRY}
+ ${unit_number} ${floor_number} ${room_number}
+${building_name}
+${building_number} ${street_name}
+${post_box}
+ BP {}
+
+
+
+ PG
+ ${party_name}
+${street}
+${CITY} ${POSTAL_CODE}
+${COUNTRY}
+ ${post_box}
+ P.O. Box {}
+
+
+
+ PH
+ ${party_name}
+${street}
+${postal_code} ${CITY}
+${COUNTRY}
+ ${building_number} ${street_name}
+${post_box}, ${post_office}
+ P.O. Box {}
+
+
+
+ PK
+ ${party_name}
+${street}
+${CITY}–${postal_code}
+${COUNTRY}
+ ${building_number}
+${street_name}
+${unit_number}
+ House No {}
+ Sector {}
+
+
+
+ PL
+ ${attn} ${party_name}
+${street}
+${postal_code} ${CITY}
+${COUNTRY}
+ ${street_name} ${building_number}/${unit_number}
+${post_box}
+ Skrytka pocztowa {}
+
+
+
+ PM
+
+ ${party_name}
+${attn}
+${STREET}
+${POSTAL_CODE} ${CITY}
+FRANCE
+ ${unit_number} ${floor_number} ${room_number}
+${building_name}
+${building_number} ${street_name}
+${post_box}
+ BP {}
+
+
+
+ PN
+ ${attn}
+${party_name}
+${street}
+${CITY}
+${POSTAL_CODE}
+${COUNTRY}
+ ${building_name}
+${building_number} ${street_name}
+
+
+
+ PT
+ ${party_name}
+${street}
+${postal_code} ${CITY}
+${COUNTRY}
+ ${street_name} ${building_number} ${unit_number}
+${building_name}
+${post_box}
+${post_office}
+ APARTADO {}
+
+
+
+ PW
+
+ ${attn}
+${party_name}
+${street}
+${CITY} ${SUBDIVISION_CODE} ${postal_code}
+${COUNTRY}
+ ${building_name}
+${building_number} ${street_name} ${unit_number}
+${post_box}
+ PO Box {}
+
+
+
+ PY
+ ${party_name}
+${street}
+${floor_number}, ${room_number}
+${postal_code} ${CITY}, ${SUBDIVISION}
+${COUNTRY}
+ ${street_name} ${building_number}
+${building_name}
+ Nº {}
+ Piso {}
+ Depto. {}
+
+
+
+ QA
+ ${party_name}
+${attn}
+${street}
+${CITY}
+${COUNTRY}
+ ${unit_number}, ${street_name} ${building_number}
+${post_box}
+ P.O. Box {}
+
+
+
+ RE
+
+ ${party_name}
+${attn}
+${STREET}
+${POSTAL_CODE} ${CITY}
+FRANCE
+ ${unit_number} ${floor_number} ${room_number}
+${building_name}
+${building_number} ${street_name}
+${post_box}
+ BP {}
+
+
+
+ RO
+ ${attn} ${party_name}
+${street}
+${postal_code} ${CITY}
+${COUNTRY}
+ ${street_name}, ${building_number}, ${unit_number}, ${floor_number}, ${room_number}
+${building_name}
+ nr. {}
+ bl. {}
+ sc. {}
+ ap. {}
+
+
+
+ RU
+ ${party_name}
+${street}
+${city}
+${SUBDIVISION}
+${COUNTRY}
+${postal_code}
+ ${street_name}, ${building_number}, ${unit_number}, ${room_number}
+ d. {}
+ kv. {}
+ kv. {}
+
+
+
+ RS
+ ${party_name}
+${street}
+${CITY}
+${UNIT_NUMBER}
+${POSTAL_CODE}
+${COUNTRY}
+ ${street_name} ${building_number}/${room_number}
+${post_box}
+ PP {}
+
+
+
+ RW
+ ${party_name}
+${street}
+${CITY}
+${COUNTRY}
+ ${post_box}
+ B.P. {}
+
+
+
+ SA
+ ${party_name}
+${street}
+${postal_code}
+${CITY}
+${COUNTRY}
+ ${building_number} ${street_name}
+${post_box}
+ P.O. Box {}
+
+
+
+ SB
+ ${party_name}
+${street}
+${CITY}
+${COUNTRY}
+ ${post_box}
+ P.O. Box {}
+
+
+
+ SC
+ ${party_name}
+${street}
+${unit_number}
+${city}
+${SUBDIVISION}
+${COUNTRY}
+ ${post_box}
+${building_name}
+${building_number}
+${street_name}
+ P.O.Box {}
+
+
+
+ SD
+ ${party_name}
+${street}
+${postal_code}
+${CITY}
+${COUNTRY}
+ ${building_name}
+${street_name}
+${unit_number}
+ B.P. {}
SE
+ ${PARTY_NAME}
+${STREET}
+${POSTAL_CODE} ${CITY}
+${COUNTRY}
+ ${street_name} ${building_number}
+${post_box}
+ BOX {}
+
+
+
+ SG
+ ${party_name}
+${street}
+${CITY} ${POSTAL_CODE}
+${COUNTRY}
+ ${building_number} ${unit_number} ${street_name}
+${floor_number}–${room_number} ${building_name}
+ # {}
+
+
+
+ SH
+ ${party_name}
+${street}
+${CITY}
+${POSTAL_CODE}
+SOUTH ATLANTIC OCEAN
+VIA CAPE TOWN, SOUTH AFRICA
+ ${building_number} ${street_name}
+
+
+
+ SI
+ ${attn}
+${party_name}
+${street}
+${postal_code} ${CITY}
+${COUNTRY}
+ ${street_name} ${building_number}
+${post_box}
+ p.p. {}
+
+
+
+ SK
+ ${attn}
+${party_name}
+${street}
+${postal_code} ${CITY}
+${COUNTRY}
+ ${street_name} ${building_number}
+${building_name}
+${post_box}
+ P.O. Box {}
+
+
+
+ SL
+ ${party_name}
+${street}
+${CITY}
+${COUNTRY}
+ ${street_name} ${building_number}
+
+
+
+ SM
+
+ ${PARTY_NAME}
+${ATTN}
+${STREET}
+${POSTAL_CODE} ${CITY} ${SUBDIVISION_CODE}
+${COUNTRY}
+ ${building_name}
+${unit_number} ${floor_number} ${room_number}
+${street_name} ${building_number}
+${post_office}
+${post_box}
+ CASELLA POSTALE {}
+
+
+
+ SN
+ ${party_name}
+${street}
+${postal_code} ${CITY}
+${COUNTRY}
+ ${room_number}
+${building_name}
+${building_number} ${street_name}
+${unit_number}
+${post_box}
+ Appartement {}
+ BP {}
+ BP {}
+
+
+
+ SO
+ ${party_name}
+${street}
+${CITY}, ${POSTAL_CODE}
+${COUNTRY}
+ ${post_box}
+ P.O. Box {}
+
+
+
+ SR
+ ${party_name}
+${street}
+${city}
+${SUBDIVISION}
+${COUNTRY}
+ ${street_name} ${building_number}
+
+
+
+ ST
${party_name}
${street}
-${postal_code} ${city}
${COUNTRY}
-
- CH
+
+ SV
+ ${party_name}
+${STREET}
+${postal_code} ${CITY}
+${COUNTRY}
+ ${street_name} ${building_number}
+${building_name}
+${post_box}
+${post_office}
+ APARTADO POSTAL {}
+
+
+
+ SZ
${party_name}
${street}
-${postal_code} ${city}
+${CITY}
+${postal_code}
${COUNTRY}
+ ${post_box}
+ P.O. Box {}
+
+
+
+ SY
+ ${party_name}
+${street}
+${postal_code} ${CITY}
+${COUNTRY}
+ ${floor_number} ${room_number}
+${street_name} ${building_number}
+${unit_number}
+
+
+
+ TC
+
+ ${attn}
+${party_name}
+${street}
+${CITY}
+${POSTAL_CODE}
+${COUNTRY}
+ ${building_name}
+${building_number} ${street_name}
+
+
+
+ TD
+ ${party_name}
+${street}
+${CITY}
+${COUNTRY}
+ ${post_box}
+ BP {}
+
+
+
+ TG
+ ${party_name}
+${street}
+${CITY}
+${COUNTRY}
+ ${post_box}
+ B.P. {}
+
+
+
+ TH
+ ${party_name}
+${street}
+${subdivision}
+${postal_code}
+${COUNTRY}
+ ${building_name}
+${building_number}/${unit_number} ${street_name}
+${post_box}
+${post_office}
+ PO Box {}
+
+
+
+ TJ
+ ${party_name}
+${street}
+${postal_code} ${CITY}
+${COUNTRY}
+ ${street_name} ${building_number} street
+
+
+
+ TL
+ ${party_name}
+${STREET}
+${CITY} ${POSTAL_CODE}
+${post_box}
+${COUNTRY}
+ ${building_name}
+${street_name} ${building_number}
+ PO Box {}
+
+
+
+ TM
+ ${party_name}
+${street}
+${city}
+${SUBDIVISION}
+${postal_code}
+${COUNTRY}
+ ${street_name} ${building_number} ${unit_number}
+${building_name}
+${post_box}
+ otag {}
+ m/g {}
+
+
+
+ TN
+ ${party_name}
+${street}
+${postal_code} ${CITY}
+${COUNTRY}
+ ${building_number} ${street_name}
+${post_box}
+ BOITE PRIVEE {}
+
+
+
+ TR
+ ${attn}
+${party_name}
+${street}
+${postal_code} ${CITY}/${SUBDIVISION}
+${COUNTRY}
+ ${street_name} ${building_number}
+${building_name}
+
+
+
+ TT
+ ${attn}
+${party_name}
+${street}
+${CITY} ${postal_code}
+${COUNTRY}
+ ${building_number} ${street_name}
+${post_box}
+${private_bag}
+ PO Box {}
+ PO BAG {}
+
+
+
+ TV
+ ${attn}
+${party_name}
+${street}
+${POSTAL_CODE} ${city}
+${SUBDIVISION}
+${COUNTRY}
+ ${street_name} ${building_number}
+${post_box}
+ P.O.Box {}
TW
zh
- ${COUNTRY}
+ Taiwan (R.O.C.)
${postal_code}
${street}
${party_name}
+ ${street_name}
+${building_number}
+${floor_number}
@@ -731,46 +2583,48 @@ ${party_name}
${party_name}
${street}
${city}, ${subdivision} ${postal_code}
-${COUNTRY}
+Taiwan (R.O.C.)
+ ${floor_number}, ${building_number}, ${street_name}
-
- TH
- ${party_name}
+
+ TZ
+ ${attn}
+${party_name}
${street}
-${name}
-${subdivision}
-${COUNTRY}
-${postal_code}
-
-
-
- TR
- ${party_name}
-${attn}
-${street}
-${name}
-${postal_code} ${city} ${subdivision}
-${COUNTRY}
+${postal_code} ${CITY}
+${SUBDIVISION}
+TANZANIA
+ ${unit_number}
+${building_number} ${street_name}
+${post_box}
+${private_bag}
+ P.O. Box {}
+ Private Bag {}
UA
- ${party_name}
+ ${attn}
+${party_name}
${street}
-${city}
-${subdivision}
+${CITY}
+${SUBDIVISION}
${postal_code}
${COUNTRY}
+ ${street_name}, ${building_number}, ${unit_number}, ${room_number}
+ d. {}
+ kv. {}
-
- GB
+
+ UG
${party_name}
${street}
${CITY}
-${postal_code}
${COUNTRY}
+ ${post_box}
+ P.O. Box {}
@@ -778,17 +2632,202 @@ ${COUNTRY}
${attn}
${party_name}
${street}
-${city}, ${subdivision_code} ${postal_code}
+${CITY} ${SUBDIVISION_CODE} ${postal_code}
${COUNTRY}
+ ${building_name}
+${building_number} ${street_name} ${unit_number}
+${post_box}
+ PO Box {}
+
+
+
+ UY
+ ${party_name}
+${attn}
+${street}
+${postal_code} – ${CITY}, ${SUBDIVISION}
+${COUNTRY}
+ ${street_name} ${building_number} ${unit_number} ${floor_number} ${room_number}
+${building_name}
+
+
+
+ UZ
+ ${attn}
+${party_name}
+${street}
+${postal_code}, ${city}
+${COUNTRY}
+ ${street_name}, ${building_number}, ${unit_number}
+${building_name}
+${post_box}
+${post_office}
+ d. {}
+ kv. {}
+ a/ya. {}
+
+
+
+ VC
+ ${PARTY_NAME}
+${STREET}
+${CITY}
+${POSTAL_CODE}
+${COUNTRY}
+ ${street_name}
+${post_box}
+ P.O BOX {}
+
+
+
+ VA
+
+ ${PARTY_NAME}
+${ATTN}
+${STREET}
+${POSTAL_CODE} ${CITY}
+VATICAN
+ ${building_name}
+${unit_number} ${floor_number} ${room_number}
+${street_name} ${building_number}
+${post_office}
+${post_box}
+ CASELLA POSTALE {}
+
+
+
+ VE
+ ${PARTY_NAME}
+${STREET}
+${CITY} ${postal_code}, ${SUBDIVISION}
+VENEZUELA
+ ${street_name}
+${building_number}
+${floor_number}, ${room_number}
+${building_name}
+${post_box}
+ PISO {}
+ APARTAMENTO {}
+ APARTADO POSTAL Nº {}
+
+
+
+ VG
+ ${party_name}
+${street}
+${CITY} ${POSTAL_CODE}
+BRITISH VIRGIN ISLANDS
+ ${post_box}
+${building_number} ${street_name}
+ #{}
+ P.O. Box {}
VN
${party_name}
+${unit_number}
${street}
${city}
-${subdivision}
+${SUBDIVISION} ${postal_code}
${COUNTRY}
+ ${building_number} ${street_name}
+${building_name}
+ GPO {}
+
+
+
+ WF
+
+ ${party_name}
+${attn}
+${STREET}
+${POSTAL_CODE} ${CITY}
+FRANCE
+ ${unit_number} ${floor_number} ${room_number}
+${building_name}
+${building_number} ${street_name}
+${post_box}
+ BP {}
+
+
+
+ WS
+ ${party_name}
+${street}
+${city} ${POSTAL_CODE}
+${COUNTRY}
+ ${post_box}
+ PO Box {}
+
+
+
+ YE
+ ${party_name}
+${street}
+${SUBDIVISION}
+${COUNTRY}
+ ${post_box}
+ B.P. {}
+
+
+
+ YT
+
+ ${party_name}
+${attn}
+${STREET}
+${POSTAL_CODE} ${CITY}
+FRANCE
+ ${unit_number} ${floor_number} ${room_number}
+${building_name}
+${building_number} ${street_name}
+${post_box}
+ BP {}
+
+
+
+ ZA
+ ${attn}
+${party_name}
+${street}
+${CITY}
+${postal_code}
+${COUNTRY}
+ ${unit_number} ${building_name}
+${building_number} ${street_name}
+${post_box}
+${private_bag}
+${post_office}
+ PO Box {}
+ Private Bag {}
+
+
+
+ ZM
+ ${attn}
+${party_name}
+${street}
+${CITY} ${postal_code}
+${COUNTRY}
+ ${building_name}
+${building_number} ${street_name}
+${post_box}
+${private_bag}
+ P.O. Box {}
+ Private Bag {}
+
+
+
+ ZW
+ ${party_name}
+${street}
+${city}
+${SUBDIVISION}
+${COUNTRY}
+ ${building_number}–${unit_number} ${street_name}
+${post_box}
+ P.O. Box {}
diff --git a/modules/party/party.py b/modules/party/party.py
index 5f09c076a6..0b40ffdeff 100644
--- a/modules/party/party.py
+++ b/modules/party/party.py
@@ -1194,9 +1194,11 @@ class Erase(Wizard):
['type', 'code'],
[None, '****']),
(Address, [('party', '=', party_id)], True,
- ['name', 'street', 'postal_code', 'city',
- 'country', 'subdivision'],
- [None, None, None, None, None, None]),
+ ['street_unstructured', 'street_name', 'building_name',
+ 'building_number', 'unit_number', 'floor_number',
+ 'room_number', 'post_box', 'private_bag', 'post_office',
+ 'postal_code', 'city', 'country', 'subdivision'],
+ [None] * 14),
(ContactMechanism, [('party', '=', party_id)], True,
['value', 'name', 'comment'],
[None, None, None]),
diff --git a/modules/party/tests/test_module.py b/modules/party/tests/test_module.py
index e2287c4316..b3d7e3df1f 100644
--- a/modules/party/tests/test_module.py
+++ b/modules/party/tests/test_module.py
@@ -200,6 +200,31 @@ class PartyTestCase(PartyCheckEraseMixin, ModuleTestCase):
}],
})
+ @with_transaction()
+ def test_address_strip(self):
+ "Test address strip"
+ pool = Pool()
+ Address = pool.get('party.address')
+ for value, result in [
+ ('', ''),
+ (' ', ''),
+ ('\n', ''),
+ (' \n \n', ''),
+ ('foo\n\n', 'foo'),
+ (',foo', 'foo'),
+ (',,foo', 'foo'),
+ (', , foo', 'foo'),
+ ('foo, , bar', 'foo, bar'),
+ ('foo,,', 'foo'),
+ ('foo, , ', 'foo'),
+ (',/–foo,/–', 'foo'),
+ ('foo, /bar', 'foo/bar'),
+ ('foo, /, bar', 'foo, bar'),
+ ('foo,/bar\nfoo, –\n/bar, foo', 'foo/bar\nfoo\nbar, foo'),
+ ]:
+ with self.subTest(value=value):
+ self.assertEqual(Address._strip(value), result)
+
@with_transaction()
def test_address(self):
'Create address'
@@ -226,6 +251,35 @@ class PartyTestCase(PartyCheckEraseMixin, ModuleTestCase):
"St sample, 15\n"
"City")
+ @with_transaction()
+ def test_address_structured(self):
+ "Test address structured"
+ pool = Pool()
+ Address = pool.get('party.address')
+ Country = pool.get('country.country')
+
+ us = Country(code='US', name="US")
+ us.save()
+ be = Country(code='BE', name="BE")
+ be.save()
+
+ address = Address(
+ street_name="St sample",
+ building_number="15",
+ unit_number="B",
+ floor_number=1,
+ room_number=3,
+ )
+
+ for country, result in [
+ (None, "St sample 15/B/1/3"),
+ (us, "15 St sample B"),
+ (be, "St sample 15 box B"),
+ ]:
+ with self.subTest(country=country.code if country else None):
+ address.country = country
+ self.assertEqual(address.street, result)
+
@with_transaction()
def test_address_autocomplete_postal_code(self):
"Test autocomplete of postal code"
diff --git a/modules/party/view/address_form.xml b/modules/party/view/address_form.xml
index be22c9f673..902c52e29f 100644
--- a/modules/party/view/address_form.xml
+++ b/modules/party/view/address_form.xml
@@ -16,12 +16,35 @@ this repository contains the full copyright notices and license terms. -->
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/party/view/address_form_simple.xml b/modules/party/view/address_form_simple.xml
index 65caeb975e..89f21ee4d8 100644
--- a/modules/party/view/address_form_simple.xml
+++ b/modules/party/view/address_form_simple.xml
@@ -15,12 +15,36 @@ this repository contains the full copyright notices and license terms. -->
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/party/view/address_format_form.xml b/modules/party/view/address_format_form.xml
index aeb522e751..ee448966ae 100644
--- a/modules/party/view/address_format_form.xml
+++ b/modules/party/view/address_format_form.xml
@@ -8,4 +8,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/party/view/address_tree.xml b/modules/party/view/address_tree.xml
index 1d29a335b2..7986fc58cd 100644
--- a/modules/party/view/address_tree.xml
+++ b/modules/party/view/address_tree.xml
@@ -4,7 +4,6 @@ this repository contains the full copyright notices and license terms. -->
-
diff --git a/modules/party/view/address_tree_sequence.xml b/modules/party/view/address_tree_sequence.xml
index 3b6d1fbef0..0e424fe752 100644
--- a/modules/party/view/address_tree_sequence.xml
+++ b/modules/party/view/address_tree_sequence.xml
@@ -4,7 +4,6 @@ this repository contains the full copyright notices and license terms. -->
-