forked from CGM_Public/pretix_original
Compare commits
8 Commits
guest-hand
...
release/3.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5094e5e4ec | ||
|
|
222cab115e | ||
|
|
7809f8ac1a | ||
|
|
839c76769c | ||
|
|
8b4cf9db70 | ||
|
|
099ab079f9 | ||
|
|
56c861036c | ||
|
|
211fddf308 |
@@ -1 +1 @@
|
|||||||
__version__ = "3.14.0"
|
__version__ = "3.14.2"
|
||||||
|
|||||||
@@ -392,6 +392,6 @@ class EventSettingsView(views.APIView):
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
if any(p in s.changed_data for p in SETTINGS_AFFECTING_CSS):
|
if any(p in s.changed_data for p in SETTINGS_AFFECTING_CSS):
|
||||||
regenerate_css.apply_async(args=(request.organizer.pk,))
|
regenerate_css.apply_async(args=(request.event.pk,))
|
||||||
s = EventSettingsSerializer(instance=request.event.settings, event=request.event)
|
s = EventSettingsSerializer(instance=request.event.settings, event=request.event)
|
||||||
return Response(s.data)
|
return Response(s.data)
|
||||||
|
|||||||
@@ -9,20 +9,19 @@ import pycountry
|
|||||||
import pytz
|
import pytz
|
||||||
import vat_moss.errors
|
import vat_moss.errors
|
||||||
import vat_moss.id
|
import vat_moss.id
|
||||||
from babel import localedata
|
from babel import Locale
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.core.validators import MaxValueValidator, MinValueValidator
|
from django.core.validators import MaxValueValidator, MinValueValidator
|
||||||
from django.db.models import QuerySet
|
from django.db.models import QuerySet
|
||||||
from django.forms import Select
|
from django.forms import Select
|
||||||
|
from django.utils import translation
|
||||||
from django.utils.formats import date_format
|
from django.utils.formats import date_format
|
||||||
from django.utils.html import escape
|
from django.utils.html import escape
|
||||||
from django.utils.safestring import mark_safe
|
from django.utils.safestring import mark_safe
|
||||||
from django.utils.timezone import get_current_timezone
|
from django.utils.timezone import get_current_timezone
|
||||||
from django.utils.translation import (
|
from django.utils.translation import gettext_lazy as _, pgettext_lazy
|
||||||
get_language, gettext_lazy as _, pgettext_lazy,
|
|
||||||
)
|
|
||||||
from django_countries import countries
|
from django_countries import countries
|
||||||
from django_countries.fields import Country, CountryField
|
from django_countries.fields import Country, CountryField
|
||||||
from phonenumber_field.formfields import PhoneNumberField
|
from phonenumber_field.formfields import PhoneNumberField
|
||||||
@@ -35,7 +34,9 @@ from pretix.base.forms.widgets import (
|
|||||||
BusinessBooleanRadio, DatePickerWidget, SplitDateTimePickerWidget,
|
BusinessBooleanRadio, DatePickerWidget, SplitDateTimePickerWidget,
|
||||||
TimePickerWidget, UploadedFileWidget,
|
TimePickerWidget, UploadedFileWidget,
|
||||||
)
|
)
|
||||||
from pretix.base.i18n import get_language_without_region, language
|
from pretix.base.i18n import (
|
||||||
|
get_babel_locale, get_language_without_region, language,
|
||||||
|
)
|
||||||
from pretix.base.models import InvoiceAddress, Question, QuestionOption
|
from pretix.base.models import InvoiceAddress, Question, QuestionOption
|
||||||
from pretix.base.models.tax import (
|
from pretix.base.models.tax import (
|
||||||
EU_COUNTRIES, cc_to_vat_prefix, is_eu_country,
|
EU_COUNTRIES, cc_to_vat_prefix, is_eu_country,
|
||||||
@@ -204,7 +205,47 @@ class NamePartsFormField(forms.MultiValueField):
|
|||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
class WrappedPhonePrefixSelect(Select):
|
||||||
|
initial = None
|
||||||
|
|
||||||
|
def __init__(self, initial=None):
|
||||||
|
choices = [("", "---------")]
|
||||||
|
language = get_babel_locale() # changed from default implementation that used the django locale
|
||||||
|
locale = Locale(translation.to_locale(language))
|
||||||
|
for prefix, values in _COUNTRY_CODE_TO_REGION_CODE.items():
|
||||||
|
prefix = "+%d" % prefix
|
||||||
|
if initial and initial in values:
|
||||||
|
self.initial = prefix
|
||||||
|
for country_code in values:
|
||||||
|
country_name = locale.territories.get(country_code)
|
||||||
|
if country_name:
|
||||||
|
choices.append((prefix, "{} {}".format(country_name, prefix)))
|
||||||
|
super().__init__(choices=sorted(choices, key=lambda item: item[1]))
|
||||||
|
|
||||||
|
def render(self, name, value, *args, **kwargs):
|
||||||
|
return super().render(name, value or self.initial, *args, **kwargs)
|
||||||
|
|
||||||
|
def get_context(self, name, value, attrs):
|
||||||
|
if value and self.choices[1][0] != value:
|
||||||
|
matching_choices = len([1 for p, c in self.choices if p == value])
|
||||||
|
if matching_choices > 1:
|
||||||
|
# Some countries share a phone pretix, for example +1 is used all over the Americas.
|
||||||
|
# This causes a UX problem: If the default value or the existing data is +12125552368,
|
||||||
|
# the widget will just show the first <option> entry with value="+1" as selected,
|
||||||
|
# which alphabetically is America Samoa, although most numbers statistically are from
|
||||||
|
# the US. As a workaround, we detect this case and add an aditional choice value with
|
||||||
|
# just <option value="+1">+1</option> without an explicit country.
|
||||||
|
self.choices.insert(1, (value, value))
|
||||||
|
context = super().get_context(name, value, attrs)
|
||||||
|
return context
|
||||||
|
|
||||||
|
|
||||||
class WrappedPhoneNumberPrefixWidget(PhoneNumberPrefixWidget):
|
class WrappedPhoneNumberPrefixWidget(PhoneNumberPrefixWidget):
|
||||||
|
|
||||||
|
def __init__(self, attrs=None, initial=None):
|
||||||
|
widgets = (WrappedPhonePrefixSelect(initial), forms.TextInput())
|
||||||
|
super(PhoneNumberPrefixWidget, self).__init__(widgets, attrs)
|
||||||
|
|
||||||
def render(self, name, value, attrs=None, renderer=None):
|
def render(self, name, value, attrs=None, renderer=None):
|
||||||
output = super().render(name, value, attrs, renderer)
|
output = super().render(name, value, attrs, renderer)
|
||||||
return mark_safe(self.format_output(output))
|
return mark_safe(self.format_output(output))
|
||||||
@@ -564,13 +605,7 @@ class BaseQuestionsForm(forms.Form):
|
|||||||
if q.valid_datetime_max:
|
if q.valid_datetime_max:
|
||||||
field.validators.append(MaxDateTimeValidator(q.valid_datetime_max))
|
field.validators.append(MaxDateTimeValidator(q.valid_datetime_max))
|
||||||
elif q.type == Question.TYPE_PHONENUMBER:
|
elif q.type == Question.TYPE_PHONENUMBER:
|
||||||
babel_locale = 'en'
|
with language(get_babel_locale()):
|
||||||
# Babel, and therefore django-phonenumberfield, do not support our custom locales such das de_Informal
|
|
||||||
if localedata.exists(get_language()):
|
|
||||||
babel_locale = get_language()
|
|
||||||
elif localedata.exists(get_language()[:2]):
|
|
||||||
babel_locale = get_language()[:2]
|
|
||||||
with language(babel_locale):
|
|
||||||
default_country = guess_country(event)
|
default_country = guess_country(event)
|
||||||
default_prefix = None
|
default_prefix = None
|
||||||
for prefix, values in _COUNTRY_CODE_TO_REGION_CODE.items():
|
for prefix, values in _COUNTRY_CODE_TO_REGION_CODE.items():
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
|
|
||||||
|
from babel import localedata
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.utils import translation
|
from django.utils import translation
|
||||||
from django.utils.formats import date_format, number_format
|
from django.utils.formats import date_format, number_format
|
||||||
@@ -69,6 +70,16 @@ class LazyNumber:
|
|||||||
ALLOWED_LANGUAGES = dict(settings.LANGUAGES)
|
ALLOWED_LANGUAGES = dict(settings.LANGUAGES)
|
||||||
|
|
||||||
|
|
||||||
|
def get_babel_locale():
|
||||||
|
babel_locale = 'en'
|
||||||
|
# Babel, and therefore django-phonenumberfield, do not support our custom locales such das de_Informal
|
||||||
|
if localedata.exists(translation.get_language()):
|
||||||
|
babel_locale = translation.get_language()
|
||||||
|
elif localedata.exists(translation.get_language()[:2]):
|
||||||
|
babel_locale = translation.get_language()[:2]
|
||||||
|
return babel_locale
|
||||||
|
|
||||||
|
|
||||||
def get_language_without_region(lng=None):
|
def get_language_without_region(lng=None):
|
||||||
"""
|
"""
|
||||||
Returns the currently active language, but strips what pretix calls a ``region``. For example,
|
Returns the currently active language, but strips what pretix calls a ``region``. For example,
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ from pretix.helpers.countries import CachedCountries
|
|||||||
from pretix.multidomain.models import KnownDomain
|
from pretix.multidomain.models import KnownDomain
|
||||||
from pretix.multidomain.urlreverse import build_absolute_uri
|
from pretix.multidomain.urlreverse import build_absolute_uri
|
||||||
from pretix.plugins.banktransfer.payment import BankTransfer
|
from pretix.plugins.banktransfer.payment import BankTransfer
|
||||||
from pretix.presale.style import get_fonts
|
|
||||||
|
|
||||||
|
|
||||||
class EventWizardFoundationForm(forms.Form):
|
class EventWizardFoundationForm(forms.Form):
|
||||||
@@ -549,9 +548,6 @@ class EventSettingsForm(SettingsForm):
|
|||||||
if not self.event.has_subevents:
|
if not self.event.has_subevents:
|
||||||
del self.fields['frontpage_subevent_ordering']
|
del self.fields['frontpage_subevent_ordering']
|
||||||
del self.fields['event_list_type']
|
del self.fields['event_list_type']
|
||||||
self.fields['primary_font'].choices += [
|
|
||||||
(a, {"title": a, "data": v}) for a, v in get_fonts().items()
|
|
||||||
]
|
|
||||||
|
|
||||||
# create "virtual" fields for better UX when editing <name>_asked and <name>_required fields
|
# create "virtual" fields for better UX when editing <name>_asked and <name>_required fields
|
||||||
self.virtual_keys = []
|
self.virtual_keys = []
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ class GeoCodeView(LoginRequiredMixin, View):
|
|||||||
gs = GlobalSettingsObject()
|
gs = GlobalSettingsObject()
|
||||||
if gs.settings.opencagedata_apikey:
|
if gs.settings.opencagedata_apikey:
|
||||||
res = self._use_opencage(q)
|
res = self._use_opencage(q)
|
||||||
if gs.settings.mapquest_apikey:
|
elif gs.settings.mapquest_apikey:
|
||||||
res = self._use_mapquest(q)
|
res = self._use_mapquest(q)
|
||||||
else:
|
else:
|
||||||
return JsonResponse({
|
return JsonResponse({
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
from itertools import chain
|
from itertools import chain
|
||||||
|
|
||||||
from babel import localedata
|
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.utils.encoding import force_str
|
from django.utils.encoding import force_str
|
||||||
from django.utils.translation import get_language, gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from phonenumber_field.formfields import PhoneNumberField
|
from phonenumber_field.formfields import PhoneNumberField
|
||||||
from phonenumber_field.phonenumber import PhoneNumber
|
from phonenumber_field.phonenumber import PhoneNumber
|
||||||
from phonenumbers import NumberParseException
|
from phonenumbers import NumberParseException
|
||||||
@@ -14,7 +13,7 @@ from pretix.base.forms.questions import (
|
|||||||
BaseInvoiceAddressForm, BaseQuestionsForm, WrappedPhoneNumberPrefixWidget,
|
BaseInvoiceAddressForm, BaseQuestionsForm, WrappedPhoneNumberPrefixWidget,
|
||||||
guess_country,
|
guess_country,
|
||||||
)
|
)
|
||||||
from pretix.base.i18n import language
|
from pretix.base.i18n import get_babel_locale, language
|
||||||
from pretix.base.validators import EmailBanlistValidator
|
from pretix.base.validators import EmailBanlistValidator
|
||||||
from pretix.presale.signals import contact_form_fields
|
from pretix.presale.signals import contact_form_fields
|
||||||
|
|
||||||
@@ -39,13 +38,7 @@ class ContactForm(forms.Form):
|
|||||||
)
|
)
|
||||||
|
|
||||||
if self.event.settings.order_phone_asked:
|
if self.event.settings.order_phone_asked:
|
||||||
babel_locale = 'en'
|
with language(get_babel_locale()):
|
||||||
# Babel, and therefore django-phonenumberfield, do not support our custom locales such as de_Informal
|
|
||||||
if localedata.exists(get_language()):
|
|
||||||
babel_locale = get_language()
|
|
||||||
elif localedata.exists(get_language()[:2]):
|
|
||||||
babel_locale = get_language()[:2]
|
|
||||||
with language(babel_locale):
|
|
||||||
default_country = guess_country(self.event)
|
default_country = guess_country(self.event)
|
||||||
default_prefix = None
|
default_prefix = None
|
||||||
for prefix, values in _COUNTRY_CODE_TO_REGION_CODE.items():
|
for prefix, values in _COUNTRY_CODE_TO_REGION_CODE.items():
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ class WidgetCartTest(CartTestMixin, TestCase):
|
|||||||
data = json.loads(response.content.decode())
|
data = json.loads(response.content.decode())
|
||||||
assert data == {
|
assert data == {
|
||||||
"name": "30C3",
|
"name": "30C3",
|
||||||
"date_range": "Dec. 26, 2021 00:00",
|
"date_range": f"Dec. 26, {self.event.date_from.year} 00:00",
|
||||||
"currency": "EUR",
|
"currency": "EUR",
|
||||||
"show_variations_expanded": False,
|
"show_variations_expanded": False,
|
||||||
"display_net_prices": False,
|
"display_net_prices": False,
|
||||||
@@ -276,7 +276,7 @@ class WidgetCartTest(CartTestMixin, TestCase):
|
|||||||
data = json.loads(response.content.decode())
|
data = json.loads(response.content.decode())
|
||||||
assert data == {
|
assert data == {
|
||||||
"name": "30C3",
|
"name": "30C3",
|
||||||
"date_range": "Dec. 26, 2021 00:00",
|
"date_range": f"Dec. 26, {self.event.date_from.year} 00:00",
|
||||||
"currency": "EUR",
|
"currency": "EUR",
|
||||||
"show_variations_expanded": False,
|
"show_variations_expanded": False,
|
||||||
"display_net_prices": False,
|
"display_net_prices": False,
|
||||||
@@ -327,7 +327,7 @@ class WidgetCartTest(CartTestMixin, TestCase):
|
|||||||
data = json.loads(response.content.decode())
|
data = json.loads(response.content.decode())
|
||||||
assert data == {
|
assert data == {
|
||||||
"name": "30C3",
|
"name": "30C3",
|
||||||
"date_range": "Dec. 26, 2021 00:00",
|
"date_range": f"Dec. 26, {self.event.date_from.year} 00:00",
|
||||||
"currency": "EUR",
|
"currency": "EUR",
|
||||||
"show_variations_expanded": False,
|
"show_variations_expanded": False,
|
||||||
"display_net_prices": False,
|
"display_net_prices": False,
|
||||||
@@ -394,7 +394,7 @@ class WidgetCartTest(CartTestMixin, TestCase):
|
|||||||
data = json.loads(response.content.decode())
|
data = json.loads(response.content.decode())
|
||||||
assert data == {
|
assert data == {
|
||||||
"name": "30C3",
|
"name": "30C3",
|
||||||
"date_range": "Dec. 26, 2021 00:00",
|
"date_range": f"Dec. 26, {self.event.date_from.year} 00:00",
|
||||||
"currency": "EUR",
|
"currency": "EUR",
|
||||||
'poweredby': '<a href="https://pretix.eu" target="_blank" rel="noopener">event ticketing powered by pretix</a>',
|
'poweredby': '<a href="https://pretix.eu" target="_blank" rel="noopener">event ticketing powered by pretix</a>',
|
||||||
"show_variations_expanded": False,
|
"show_variations_expanded": False,
|
||||||
|
|||||||
Reference in New Issue
Block a user