diff --git a/src/pretix/base/forms/questions.py b/src/pretix/base/forms/questions.py
index aee2ada677..f223ee952a 100644
--- a/src/pretix/base/forms/questions.py
+++ b/src/pretix/base/forms/questions.py
@@ -83,8 +83,8 @@ from pretix.base.services.tax import (
VATIDFinalError, VATIDTemporaryError, validate_vat_id,
)
from pretix.base.settings import (
- COUNTRIES_WITH_STATE_IN_ADDRESS, PERSON_NAME_SALUTATIONS,
- PERSON_NAME_SCHEMES, PERSON_NAME_TITLE_GROUPS,
+ COUNTRIES_WITH_STATE_IN_ADDRESS, COUNTRY_STATE_LABEL,
+ PERSON_NAME_SALUTATIONS, PERSON_NAME_SCHEMES, PERSON_NAME_TITLE_GROUPS,
)
from pretix.base.templatetags.rich_text import rich_text
from pretix.base.timemachine import time_machine_now
@@ -721,7 +721,7 @@ class BaseQuestionsForm(forms.Form):
'data-country-information-url': reverse('js_helpers.states'),
}),
)
- c = [('', pgettext_lazy('address', 'Select state'))]
+ c = [('', '---')]
fprefix = str(self.prefix) + '-' if self.prefix is not None and self.prefix != '-' else ''
cc = None
state = None
@@ -1079,7 +1079,7 @@ class BaseInvoiceAddressForm(forms.ModelForm):
self.fields['country'].choices = CachedCountries()
self.fields['country'].widget.attrs['data-country-information-url'] = reverse('js_helpers.states')
- c = [('', pgettext_lazy('address', 'Select state'))]
+ c = [('', '---')]
fprefix = self.prefix + '-' if self.prefix else ''
cc = None
if fprefix + 'country' in self.data:
@@ -1088,16 +1088,19 @@ class BaseInvoiceAddressForm(forms.ModelForm):
cc = str(self.initial['country'])
elif self.instance and self.instance.country:
cc = str(self.instance.country)
+ state_label = pgettext_lazy('address', 'State')
if cc and cc in COUNTRIES_WITH_STATE_IN_ADDRESS:
types, form = COUNTRIES_WITH_STATE_IN_ADDRESS[cc]
statelist = [s for s in pycountry.subdivisions.get(country_code=cc) if s.type in types]
c += sorted([(s.code[3:], s.name) for s in statelist], key=lambda s: s[1])
+ if cc in COUNTRY_STATE_LABEL:
+ state_label = COUNTRY_STATE_LABEL[cc]
elif fprefix + 'state' in self.data:
self.data = self.data.copy()
del self.data[fprefix + 'state']
self.fields['state'] = forms.ChoiceField(
- label=pgettext_lazy('address', 'State'),
+ label=state_label,
required=False,
choices=c,
widget=forms.Select(attrs={
diff --git a/src/pretix/base/settings.py b/src/pretix/base/settings.py
index 2311e62a46..9faa33722b 100644
--- a/src/pretix/base/settings.py
+++ b/src/pretix/base/settings.py
@@ -3712,6 +3712,14 @@ COUNTRIES_WITH_STATE_IN_ADDRESS = {
'MY': (['State', 'Federal territory'], 'long'),
'MX': (['State', 'Federal district'], 'short'),
'US': (['State', 'Outlying area', 'District'], 'short'),
+ 'IT': (['Province', 'Free municipal consortium', 'Metropolitan city', 'Autonomous province',
+ 'Free municipal consortium', 'Decentralized regional entity'], 'short'),
+}
+COUNTRY_STATE_LABEL = {
+ # Countries in which the "State" field should not be called "State"
+ 'CA': pgettext_lazy('address', 'Province'),
+ 'JP': pgettext_lazy('address', 'Prefecture'),
+ 'IT': pgettext_lazy('address', 'Province'),
}
settings_hierarkey = Hierarkey(attribute_name='settings')
diff --git a/src/pretix/base/views/js_helpers.py b/src/pretix/base/views/js_helpers.py
index be180e9cd5..303578ec78 100644
--- a/src/pretix/base/views/js_helpers.py
+++ b/src/pretix/base/views/js_helpers.py
@@ -21,12 +21,15 @@
#
import pycountry
from django.http import JsonResponse
+from django.utils.translation import pgettext
from pretix.base.addressvalidation import (
COUNTRIES_WITH_STREET_ZIPCODE_AND_CITY_REQUIRED,
)
from pretix.base.models.tax import VAT_ID_COUNTRIES
-from pretix.base.settings import COUNTRIES_WITH_STATE_IN_ADDRESS
+from pretix.base.settings import (
+ COUNTRIES_WITH_STATE_IN_ADDRESS, COUNTRY_STATE_LABEL,
+)
def states(request):
@@ -35,7 +38,11 @@ def states(request):
'street': {'required': True},
'zipcode': {'required': cc in COUNTRIES_WITH_STREET_ZIPCODE_AND_CITY_REQUIRED},
'city': {'required': cc in COUNTRIES_WITH_STREET_ZIPCODE_AND_CITY_REQUIRED},
- 'state': {'visible': cc in COUNTRIES_WITH_STATE_IN_ADDRESS, 'required': cc in COUNTRIES_WITH_STATE_IN_ADDRESS},
+ 'state': {
+ 'visible': cc in COUNTRIES_WITH_STATE_IN_ADDRESS,
+ 'required': cc in COUNTRIES_WITH_STATE_IN_ADDRESS,
+ 'label': COUNTRY_STATE_LABEL.get(cc, pgettext('address', 'State')),
+ },
'vat_id': {'visible': cc in VAT_ID_COUNTRIES, 'required': False},
}
if cc not in COUNTRIES_WITH_STATE_IN_ADDRESS:
diff --git a/src/pretix/control/context.py b/src/pretix/control/context.py
index 3cdfc1b0bf..5183b13ce1 100644
--- a/src/pretix/control/context.py
+++ b/src/pretix/control/context.py
@@ -43,7 +43,7 @@ from django.utils.translation import get_language
from django_scopes import scope
from pretix.base.models.auth import StaffSession
-from pretix.base.settings import GlobalSettingsObject
+from pretix.base.settings import COUNTRY_STATE_LABEL, GlobalSettingsObject
from pretix.control.navigation import (
get_event_navigation, get_global_navigation, get_organizer_navigation,
)
@@ -140,6 +140,7 @@ def _default_context(request):
ctx['js_time_format'] = get_javascript_format('TIME_INPUT_FORMATS')
ctx['js_locale'] = get_moment_locale()
ctx['select2locale'] = get_language()[:2]
+ ctx['COUNTRY_STATE_LABEL'] = COUNTRY_STATE_LABEL
ctx['warning_update_available'] = False
ctx['warning_update_check_active'] = False
diff --git a/src/pretix/control/forms/event.py b/src/pretix/control/forms/event.py
index 98ba32d7af..f947638161 100644
--- a/src/pretix/control/forms/event.py
+++ b/src/pretix/control/forms/event.py
@@ -1475,7 +1475,9 @@ class CountriesAndEUAndStates(CountriesAndEU):
def __iter__(self):
for country_code, country_name in super().__iter__():
yield country_code, country_name
- if country_code in COUNTRIES_WITH_STATE_IN_ADDRESS:
+ if country_code in COUNTRIES_WITH_STATE_IN_ADDRESS and country_code not in {"IT"}:
+ # Special case for Italy: Provinces are used in addresses, but are too low-level to
+ # have influence on taxes, so we avoid the bloat in the list of selectable countries.
types, form = COUNTRIES_WITH_STATE_IN_ADDRESS[country_code]
yield from sorted(((state.code, country_name + " - " + state.name)
for state in pycountry.subdivisions.get(country_code=country_code)
diff --git a/src/pretix/control/templates/pretixcontrol/order/index.html b/src/pretix/control/templates/pretixcontrol/order/index.html
index af221e38e0..24c5dd964f 100644
--- a/src/pretix/control/templates/pretixcontrol/order/index.html
+++ b/src/pretix/control/templates/pretixcontrol/order/index.html
@@ -9,6 +9,7 @@
{% load eventsignal %}
{% load l10n %}
{% load phone_format %}
+{% load getitem %}
{% block title %}
{% blocktrans trimmed with code=order.code %}
Order details: {{ code }}
@@ -560,8 +561,8 @@
{% if line.street or line.zipcode or line.city or line.country %}
{{ line.street|default_if_none:""|linebreaksbr }}
{{ line.zipcode|default_if_none:"" }} {{ line.city|default_if_none:"" }}
+ {% if line.state %}{{ line.state_for_address }}
{% endif %}
{{ line.country.name|default_if_none:"" }}
- {% if line.state %}
{{ line.state }}{% endif %}
{% else %}
{% trans "not answered" %}
{% endif %}
@@ -959,7 +960,7 @@
{% trans "Country" %}
{{ order.invoice_address.country.name|default:order.invoice_address.country_old }}
{% if order.invoice_address.state %}
- {% trans "State" context "address" %}
+ {% trans "State" context "address" as state_label %}{{ COUNTRY_STATE_LABEL|getitem:order.invoice_address.country.code|default:state_label }}
{{ order.invoice_address.state_name }}
{% endif %}
{% if request.event.settings.invoice_address_vatid %}
diff --git a/src/pretix/presale/context.py b/src/pretix/presale/context.py
index 80a9a2f945..2bfeac2c50 100644
--- a/src/pretix/presale/context.py
+++ b/src/pretix/presale/context.py
@@ -40,7 +40,7 @@ from django.utils.translation import get_language_info
from django_scopes import get_scope
from i18nfield.strings import LazyI18nString
-from pretix.base.settings import GlobalSettingsObject
+from pretix.base.settings import COUNTRY_STATE_LABEL, GlobalSettingsObject
from pretix.helpers.i18n import (
get_javascript_format_without_seconds, get_moment_locale,
)
@@ -187,6 +187,7 @@ def _default_context(request):
ctx['html_locale'] = translation.get_language_info(get_language_without_region()).get('public_code', translation.get_language())
ctx['settings'] = pretix_settings
ctx['django_settings'] = settings
+ ctx['COUNTRY_STATE_LABEL'] = COUNTRY_STATE_LABEL
ctx['ie_deprecation_warning'] = 'MSIE' in request.headers.get('User-Agent', '') or 'Trident/' in request.headers.get('User-Agent', '')
diff --git a/src/pretix/presale/templates/pretixpresale/event/checkout_confirm.html b/src/pretix/presale/templates/pretixpresale/event/checkout_confirm.html
index b74d399aac..42156a81ed 100644
--- a/src/pretix/presale/templates/pretixpresale/event/checkout_confirm.html
+++ b/src/pretix/presale/templates/pretixpresale/event/checkout_confirm.html
@@ -4,6 +4,7 @@
{% load money %}
{% load eventurl %}
{% load eventsignal %}
+{% load getitem %}
{% block title %}{% trans "Review order" %}{% endblock %}
{% block content %}
@@ -92,7 +93,7 @@
{% trans "Country" %}
{{ addr.country.name }}
{% if addr.state %}
- {% trans "State" context "address" %}
+ {% trans "State" context "address" as state_label %}{{ COUNTRY_STATE_LABEL|getitem:addr.country.code|default:state_label }}
{{ addr.state_name }}
{% endif %}
{% if request.event.settings.invoice_address_vatid and addr.vat_id %}
diff --git a/src/pretix/presale/templates/pretixpresale/event/fragment_cart.html b/src/pretix/presale/templates/pretixpresale/event/fragment_cart.html
index 23dae50c8a..dc24d42d3a 100644
--- a/src/pretix/presale/templates/pretixpresale/event/fragment_cart.html
+++ b/src/pretix/presale/templates/pretixpresale/event/fragment_cart.html
@@ -200,8 +200,8 @@
{{ line.street|default_if_none:""|linebreaksbr }}
{{ line.zipcode|default_if_none:"" }} {{ line.city|default_if_none:"" }}
+ {% if line.state %}{{ line.state_for_address }}
{% endif %}
{{ line.country.name|default_if_none:"" }}
- {% if line.state %}
{{ line.state }}{% endif %}
{% endif %}
diff --git a/src/pretix/presale/templates/pretixpresale/event/order.html b/src/pretix/presale/templates/pretixpresale/event/order.html
index 62c9c11a83..7750f3c2cd 100644
--- a/src/pretix/presale/templates/pretixpresale/event/order.html
+++ b/src/pretix/presale/templates/pretixpresale/event/order.html
@@ -7,6 +7,7 @@
{% load eventurl %}
{% load phone_format %}
{% load rich_text %}
+{% load getitem %}
{% block title %}
{% if "thanks" in request.GET or "paid" in request.GET %}
{% trans "Thank you!" %}
@@ -319,7 +320,7 @@
{% trans "Country" %}
{{ order.invoice_address.country.name|default:order.invoice_address.country_old }}
{% if order.invoice_address.state %}
- {% trans "State" context "address" %}
+ {% trans "State" context "address" as state_label %}{{ COUNTRY_STATE_LABEL|getitem:order.invoice_address.country.code|default:state_label }}
{{ order.invoice_address.state_name }}
{% endif %}
{% if request.event.settings.invoice_address_vatid and order.invoice_address.vat_id %}
diff --git a/src/pretix/static/pretixbase/js/addressform.js b/src/pretix/static/pretixbase/js/addressform.js
index 5cae95100d..fe29408037 100644
--- a/src/pretix/static/pretixbase/js/addressform.js
+++ b/src/pretix/static/pretixbase/js/addressform.js
@@ -44,6 +44,10 @@ $(function () {
);
}
+ if ('label' in options) {
+ dependent.closest(".form-group").find(".control-label").text(options.label);
+ }
+
const required = 'required' in options && options.required && isRequired && visible;
dependent.closest(".form-group").toggle(visible).toggleClass('required', required);
dependent.prop("required", required);