forked from CGM_Public/pretix_original
Compare commits
42
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eff815056b | ||
|
|
45391b104a | ||
|
|
54d3d20d70 | ||
|
|
be1cb12286 | ||
|
|
c65b7f711d | ||
|
|
8e3d5511e2 | ||
|
|
9acfcf2526 | ||
|
|
32fd9f2f4d | ||
|
|
47ec03baac | ||
|
|
04884ce874 | ||
|
|
3337783d1f | ||
|
|
391bbc25f8 | ||
|
|
68017cc8cb | ||
|
|
5fee16035f | ||
|
|
6d32aa5220 | ||
|
|
3461c59cfe | ||
|
|
21b4dacee9 | ||
|
|
2663e9ff32 | ||
|
|
a601c75923 | ||
|
|
f94227f00f | ||
|
|
a0c1e5369c | ||
|
|
633bfcf73a | ||
|
|
0d3b5b82c1 | ||
|
|
ab95f33546 | ||
|
|
5034b366c5 | ||
|
|
03d3c389da | ||
|
|
3e934acfa0 | ||
|
|
d2a364e848 | ||
|
|
2824b40299 | ||
|
|
c6c2c90908 | ||
|
|
d4ae7df2ec | ||
|
|
79dd7fb596 | ||
|
|
5ed87cd019 | ||
|
|
ccdcbe0cc5 | ||
|
|
4f8607a9db | ||
|
|
57ecaa2676 | ||
|
|
96fd2b1a95 | ||
|
|
5cf24fb6a6 | ||
|
|
1d2ea35a39 | ||
|
|
ac98ae7941 | ||
|
|
a0d055e202 | ||
|
|
27ec5ca006 |
@@ -352,12 +352,12 @@ Fetching individual invoices
|
|||||||
|
|
||||||
:param organizer: The ``slug`` field of the organizer to fetch
|
:param organizer: The ``slug`` field of the organizer to fetch
|
||||||
:param event: The ``slug`` field of the event to fetch
|
:param event: The ``slug`` field of the event to fetch
|
||||||
:param invoice_no: The ``invoice_no`` field of the invoice to fetch
|
:param number: The ``number`` field of the invoice to fetch
|
||||||
:statuscode 200: no error
|
:statuscode 200: no error
|
||||||
:statuscode 401: Authentication failure
|
:statuscode 401: Authentication failure
|
||||||
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to view this resource.
|
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to view this resource.
|
||||||
|
|
||||||
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/invoices/(invoice_no)/download/
|
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/invoices/(number)/download/
|
||||||
|
|
||||||
Download an invoice in PDF format.
|
Download an invoice in PDF format.
|
||||||
|
|
||||||
@@ -384,7 +384,7 @@ Fetching individual invoices
|
|||||||
|
|
||||||
:param organizer: The ``slug`` field of the organizer to fetch
|
:param organizer: The ``slug`` field of the organizer to fetch
|
||||||
:param event: The ``slug`` field of the event to fetch
|
:param event: The ``slug`` field of the event to fetch
|
||||||
:param invoice_no: The ``invoice_no`` field of the invoice to fetch
|
:param number: The ``number`` field of the invoice to fetch
|
||||||
:statuscode 200: no error
|
:statuscode 200: no error
|
||||||
:statuscode 401: Authentication failure
|
:statuscode 401: Authentication failure
|
||||||
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to view this resource.
|
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to view this resource.
|
||||||
@@ -397,7 +397,7 @@ Modifying invoices
|
|||||||
|
|
||||||
Invoices cannot be edited directly, but the following actions can be triggered:
|
Invoices cannot be edited directly, but the following actions can be triggered:
|
||||||
|
|
||||||
.. http:post:: /api/v1/organizers/(organizer)/events/(event)/invoices/(invoice_no)/reissue/
|
.. http:post:: /api/v1/organizers/(organizer)/events/(event)/invoices/(number)/reissue/
|
||||||
|
|
||||||
Cancels the invoice and creates a new one.
|
Cancels the invoice and creates a new one.
|
||||||
|
|
||||||
@@ -419,13 +419,13 @@ Invoices cannot be edited directly, but the following actions can be triggered:
|
|||||||
|
|
||||||
:param organizer: The ``slug`` field of the organizer to fetch
|
:param organizer: The ``slug`` field of the organizer to fetch
|
||||||
:param event: The ``slug`` field of the event to fetch
|
:param event: The ``slug`` field of the event to fetch
|
||||||
:param invoice_no: The ``invoice_no`` field of the invoice to reissue
|
:param number: The ``number`` field of the invoice to reissue
|
||||||
:statuscode 200: no error
|
:statuscode 200: no error
|
||||||
:statuscode 400: The invoice has already been canceled
|
:statuscode 400: The invoice has already been canceled
|
||||||
:statuscode 401: Authentication failure
|
:statuscode 401: Authentication failure
|
||||||
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to change this resource.
|
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to change this resource.
|
||||||
|
|
||||||
.. http:post:: /api/v1/organizers/(organizer)/events/(event)/invoices/(invoice_no)/regenerate/
|
.. http:post:: /api/v1/organizers/(organizer)/events/(event)/invoices/(number)/regenerate/
|
||||||
|
|
||||||
Re-generates the invoice from order data.
|
Re-generates the invoice from order data.
|
||||||
|
|
||||||
@@ -447,7 +447,7 @@ Invoices cannot be edited directly, but the following actions can be triggered:
|
|||||||
|
|
||||||
:param organizer: The ``slug`` field of the organizer to fetch
|
:param organizer: The ``slug`` field of the organizer to fetch
|
||||||
:param event: The ``slug`` field of the event to fetch
|
:param event: The ``slug`` field of the event to fetch
|
||||||
:param invoice_no: The ``invoice_no`` field of the invoice to regenerate
|
:param number: The ``number`` field of the invoice to regenerate
|
||||||
:statuscode 200: no error
|
:statuscode 200: no error
|
||||||
:statuscode 400: The invoice has already been canceled
|
:statuscode 400: The invoice has already been canceled
|
||||||
:statuscode 401: Authentication failure
|
:statuscode 401: Authentication failure
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ class NativeAuthBackend(BaseAuthBackend):
|
|||||||
to log in.
|
to log in.
|
||||||
"""
|
"""
|
||||||
d = OrderedDict([
|
d = OrderedDict([
|
||||||
('email', forms.EmailField(label=_("E-mail"), max_length=254,
|
('email', forms.EmailField(label=_("Email"), max_length=254,
|
||||||
widget=forms.EmailInput(attrs={'autofocus': 'autofocus'}))),
|
widget=forms.EmailInput(attrs={'autofocus': 'autofocus'}))),
|
||||||
('password', forms.CharField(label=_("Password"), widget=forms.PasswordInput,
|
('password', forms.CharField(label=_("Password"), widget=forms.PasswordInput,
|
||||||
max_length=4096)),
|
max_length=4096)),
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ def test_custom_smtp_backend(backend: T, from_addr: str) -> None:
|
|||||||
|
|
||||||
class BaseHTMLMailRenderer:
|
class BaseHTMLMailRenderer:
|
||||||
"""
|
"""
|
||||||
This is the base class for all HTML e-mail renderers.
|
This is the base class for all HTML email renderers.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, event: Event, organizer=None):
|
def __init__(self, event: Event, organizer=None):
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ class CustomerListExporter(OrganizerLevelExportMixin, ListExporter):
|
|||||||
_('Customer ID'),
|
_('Customer ID'),
|
||||||
_('SSO provider'),
|
_('SSO provider'),
|
||||||
_('External identifier'),
|
_('External identifier'),
|
||||||
_('E-mail'),
|
_('Email'),
|
||||||
_('Phone number'),
|
_('Phone number'),
|
||||||
_('Full name'),
|
_('Full name'),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -199,7 +199,7 @@ class InvoiceDataExporter(InvoiceExporterMixin, MultiSheetListExporter):
|
|||||||
_('Invoice number'),
|
_('Invoice number'),
|
||||||
_('Date'),
|
_('Date'),
|
||||||
_('Order code'),
|
_('Order code'),
|
||||||
_('E-mail address'),
|
_('Email address'),
|
||||||
_('Invoice type'),
|
_('Invoice type'),
|
||||||
_('Cancellation of'),
|
_('Cancellation of'),
|
||||||
_('Language'),
|
_('Language'),
|
||||||
@@ -326,7 +326,7 @@ class InvoiceDataExporter(InvoiceExporterMixin, MultiSheetListExporter):
|
|||||||
_('Event start date'),
|
_('Event start date'),
|
||||||
_('Date'),
|
_('Date'),
|
||||||
_('Order code'),
|
_('Order code'),
|
||||||
_('E-mail address'),
|
_('Email address'),
|
||||||
_('Invoice type'),
|
_('Invoice type'),
|
||||||
_('Cancellation of'),
|
_('Cancellation of'),
|
||||||
_('Invoice sender:') + ' ' + _('Name'),
|
_('Invoice sender:') + ' ' + _('Name'),
|
||||||
|
|||||||
@@ -284,7 +284,7 @@ class OrderListExporter(MultiSheetListExporter):
|
|||||||
headers.append(_('Comment'))
|
headers.append(_('Comment'))
|
||||||
headers.append(_('Follow-up date'))
|
headers.append(_('Follow-up date'))
|
||||||
headers.append(_('Positions'))
|
headers.append(_('Positions'))
|
||||||
headers.append(_('E-mail address verified'))
|
headers.append(_('Email address verified'))
|
||||||
headers.append(_('External customer ID'))
|
headers.append(_('External customer ID'))
|
||||||
headers.append(_('Payment providers'))
|
headers.append(_('Payment providers'))
|
||||||
if form_data.get('include_payment_amounts'):
|
if form_data.get('include_payment_amounts'):
|
||||||
@@ -655,7 +655,7 @@ class OrderListExporter(MultiSheetListExporter):
|
|||||||
headers += [
|
headers += [
|
||||||
_('Sales channel'),
|
_('Sales channel'),
|
||||||
_('Order locale'),
|
_('Order locale'),
|
||||||
_('E-mail address verified'),
|
_('Email address verified'),
|
||||||
_('External customer ID'),
|
_('External customer ID'),
|
||||||
_('Check-in lists'),
|
_('Check-in lists'),
|
||||||
_('Payment providers'),
|
_('Payment providers'),
|
||||||
|
|||||||
@@ -254,7 +254,7 @@ class PasswordRecoverForm(forms.Form):
|
|||||||
|
|
||||||
class PasswordForgotForm(forms.Form):
|
class PasswordForgotForm(forms.Form):
|
||||||
email = forms.EmailField(
|
email = forms.EmailField(
|
||||||
label=_('E-mail'),
|
label=_('Email'),
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ from django.core.validators import (
|
|||||||
from django.db.models import QuerySet
|
from django.db.models import QuerySet
|
||||||
from django.forms import Select, widgets
|
from django.forms import Select, widgets
|
||||||
from django.forms.widgets import FILE_INPUT_CONTRADICTION
|
from django.forms.widgets import FILE_INPUT_CONTRADICTION
|
||||||
|
from django.urls import reverse
|
||||||
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
|
||||||
@@ -77,7 +78,7 @@ from pretix.base.i18n import (
|
|||||||
get_babel_locale, get_language_without_region, language,
|
get_babel_locale, get_language_without_region, language,
|
||||||
)
|
)
|
||||||
from pretix.base.models import InvoiceAddress, Item, Question, QuestionOption
|
from pretix.base.models import InvoiceAddress, Item, Question, QuestionOption
|
||||||
from pretix.base.models.tax import VAT_ID_COUNTRIES, ask_for_vat_id
|
from pretix.base.models.tax import ask_for_vat_id
|
||||||
from pretix.base.services.tax import (
|
from pretix.base.services.tax import (
|
||||||
VATIDFinalError, VATIDTemporaryError, validate_vat_id,
|
VATIDFinalError, VATIDTemporaryError, validate_vat_id,
|
||||||
)
|
)
|
||||||
@@ -602,6 +603,7 @@ class BaseQuestionsForm(forms.Form):
|
|||||||
questions = pos.item.questions_to_ask
|
questions = pos.item.questions_to_ask
|
||||||
event = kwargs.pop('event')
|
event = kwargs.pop('event')
|
||||||
self.all_optional = kwargs.pop('all_optional', False)
|
self.all_optional = kwargs.pop('all_optional', False)
|
||||||
|
self.attendee_addresses_required = event.settings.attendee_addresses_required and not self.all_optional
|
||||||
|
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
@@ -676,7 +678,7 @@ class BaseQuestionsForm(forms.Form):
|
|||||||
|
|
||||||
if item.ask_attendee_data and event.settings.attendee_addresses_asked:
|
if item.ask_attendee_data and event.settings.attendee_addresses_asked:
|
||||||
add_fields['street'] = forms.CharField(
|
add_fields['street'] = forms.CharField(
|
||||||
required=event.settings.attendee_addresses_required and not self.all_optional,
|
required=self.attendee_addresses_required,
|
||||||
label=_('Address'),
|
label=_('Address'),
|
||||||
widget=forms.Textarea(attrs={
|
widget=forms.Textarea(attrs={
|
||||||
'rows': 2,
|
'rows': 2,
|
||||||
@@ -686,7 +688,7 @@ class BaseQuestionsForm(forms.Form):
|
|||||||
initial=(cartpos.street if cartpos else orderpos.street),
|
initial=(cartpos.street if cartpos else orderpos.street),
|
||||||
)
|
)
|
||||||
add_fields['zipcode'] = forms.CharField(
|
add_fields['zipcode'] = forms.CharField(
|
||||||
required=event.settings.attendee_addresses_required and not self.all_optional,
|
required=False,
|
||||||
max_length=30,
|
max_length=30,
|
||||||
label=_('ZIP code'),
|
label=_('ZIP code'),
|
||||||
initial=(cartpos.zipcode if cartpos else orderpos.zipcode),
|
initial=(cartpos.zipcode if cartpos else orderpos.zipcode),
|
||||||
@@ -695,7 +697,7 @@ class BaseQuestionsForm(forms.Form):
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
add_fields['city'] = forms.CharField(
|
add_fields['city'] = forms.CharField(
|
||||||
required=event.settings.attendee_addresses_required and not self.all_optional,
|
required=False,
|
||||||
label=_('City'),
|
label=_('City'),
|
||||||
max_length=255,
|
max_length=255,
|
||||||
initial=(cartpos.city if cartpos else orderpos.city),
|
initial=(cartpos.city if cartpos else orderpos.city),
|
||||||
@@ -707,11 +709,12 @@ class BaseQuestionsForm(forms.Form):
|
|||||||
add_fields['country'] = CountryField(
|
add_fields['country'] = CountryField(
|
||||||
countries=CachedCountries
|
countries=CachedCountries
|
||||||
).formfield(
|
).formfield(
|
||||||
required=event.settings.attendee_addresses_required and not self.all_optional,
|
required=self.attendee_addresses_required,
|
||||||
label=_('Country'),
|
label=_('Country'),
|
||||||
initial=country,
|
initial=country,
|
||||||
widget=forms.Select(attrs={
|
widget=forms.Select(attrs={
|
||||||
'autocomplete': 'country',
|
'autocomplete': 'country',
|
||||||
|
'data-country-information-url': reverse('js_helpers.states'),
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
c = [('', pgettext_lazy('address', 'Select state'))]
|
c = [('', pgettext_lazy('address', 'Select state'))]
|
||||||
@@ -946,9 +949,9 @@ class BaseQuestionsForm(forms.Form):
|
|||||||
d = super().clean()
|
d = super().clean()
|
||||||
|
|
||||||
if self.address_validation:
|
if self.address_validation:
|
||||||
self.cleaned_data = d = validate_address(d, True)
|
self.cleaned_data = d = validate_address(d, all_optional=not self.attendee_addresses_required)
|
||||||
|
|
||||||
if d.get('city') and d.get('country') and str(d['country']) in COUNTRIES_WITH_STATE_IN_ADDRESS:
|
if d.get('street') and d.get('country') and str(d['country']) in COUNTRIES_WITH_STATE_IN_ADDRESS:
|
||||||
if not d.get('state'):
|
if not d.get('state'):
|
||||||
self.add_error('state', _('This field is required.'))
|
self.add_error('state', _('This field is required.'))
|
||||||
|
|
||||||
@@ -1005,7 +1008,7 @@ class BaseInvoiceAddressForm(forms.ModelForm):
|
|||||||
'street': forms.Textarea(attrs={
|
'street': forms.Textarea(attrs={
|
||||||
'rows': 2,
|
'rows': 2,
|
||||||
'placeholder': _('Street and Number'),
|
'placeholder': _('Street and Number'),
|
||||||
'autocomplete': 'street-address'
|
'autocomplete': 'street-address',
|
||||||
}),
|
}),
|
||||||
'beneficiary': forms.Textarea(attrs={'rows': 3}),
|
'beneficiary': forms.Textarea(attrs={'rows': 3}),
|
||||||
'country': forms.Select(attrs={
|
'country': forms.Select(attrs={
|
||||||
@@ -1021,7 +1024,7 @@ class BaseInvoiceAddressForm(forms.ModelForm):
|
|||||||
'data-display-dependency': '#id_is_business_1',
|
'data-display-dependency': '#id_is_business_1',
|
||||||
'autocomplete': 'organization',
|
'autocomplete': 'organization',
|
||||||
}),
|
}),
|
||||||
'vat_id': forms.TextInput(attrs={'data-display-dependency': '#id_is_business_1', 'data-countries-with-vat-id': ','.join(VAT_ID_COUNTRIES)}),
|
'vat_id': forms.TextInput(attrs={'data-display-dependency': '#id_is_business_1'}),
|
||||||
'internal_reference': forms.TextInput,
|
'internal_reference': forms.TextInput,
|
||||||
}
|
}
|
||||||
labels = {
|
labels = {
|
||||||
@@ -1055,6 +1058,7 @@ class BaseInvoiceAddressForm(forms.ModelForm):
|
|||||||
])
|
])
|
||||||
|
|
||||||
self.fields['country'].choices = CachedCountries()
|
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 = [('', pgettext_lazy('address', 'Select state'))]
|
||||||
fprefix = self.prefix + '-' if self.prefix else ''
|
fprefix = self.prefix + '-' if self.prefix else ''
|
||||||
@@ -1083,6 +1087,10 @@ class BaseInvoiceAddressForm(forms.ModelForm):
|
|||||||
)
|
)
|
||||||
self.fields['state'].widget.is_required = True
|
self.fields['state'].widget.is_required = True
|
||||||
|
|
||||||
|
self.fields['street'].required = False
|
||||||
|
self.fields['zipcode'].required = False
|
||||||
|
self.fields['city'].required = False
|
||||||
|
|
||||||
# Without JavaScript the VAT ID field is not hidden, so we empty the field if a country outside the EU is selected.
|
# Without JavaScript the VAT ID field is not hidden, so we empty the field if a country outside the EU is selected.
|
||||||
if cc and not ask_for_vat_id(cc) and fprefix + 'vat_id' in self.data:
|
if cc and not ask_for_vat_id(cc) and fprefix + 'vat_id' in self.data:
|
||||||
self.data = self.data.copy()
|
self.data = self.data.copy()
|
||||||
@@ -1142,9 +1150,11 @@ class BaseInvoiceAddressForm(forms.ModelForm):
|
|||||||
data['vat_id'] = ''
|
data['vat_id'] = ''
|
||||||
if self.event.settings.invoice_address_required:
|
if self.event.settings.invoice_address_required:
|
||||||
if data.get('is_business') and not data.get('company'):
|
if data.get('is_business') and not data.get('company'):
|
||||||
raise ValidationError(_('You need to provide a company name.'))
|
raise ValidationError({"company": _('You need to provide a company name.')})
|
||||||
if not data.get('is_business') and not data.get('name_parts'):
|
if not data.get('is_business') and not data.get('name_parts'):
|
||||||
raise ValidationError(_('You need to provide your name.'))
|
raise ValidationError(_('You need to provide your name.'))
|
||||||
|
if not data.get('street') and not data.get('zipcode') and not data.get('city'):
|
||||||
|
raise ValidationError({"street": _('This field is required.')})
|
||||||
|
|
||||||
if 'vat_id' in self.changed_data or not data.get('vat_id'):
|
if 'vat_id' in self.changed_data or not data.get('vat_id'):
|
||||||
self.instance.vat_id_validated = False
|
self.instance.vat_id_validated = False
|
||||||
|
|||||||
@@ -48,10 +48,10 @@ from pretix.control.forms import SingleLanguageWidget
|
|||||||
|
|
||||||
class UserSettingsForm(forms.ModelForm):
|
class UserSettingsForm(forms.ModelForm):
|
||||||
error_messages = {
|
error_messages = {
|
||||||
'duplicate_identifier': _("There already is an account associated with this e-mail address. "
|
'duplicate_identifier': _("There already is an account associated with this email address. "
|
||||||
"Please choose a different one."),
|
"Please choose a different one."),
|
||||||
'pw_current': _("Please enter your current password if you want to change your e-mail "
|
'pw_current': _("Please enter your current password if you want to change your email address "
|
||||||
"address or password."),
|
"or password."),
|
||||||
'pw_current_wrong': _("The current password you entered was not correct."),
|
'pw_current_wrong': _("The current password you entered was not correct."),
|
||||||
'pw_mismatch': _("Please enter the same password twice"),
|
'pw_mismatch': _("Please enter the same password twice"),
|
||||||
'rate_limit': _("For security reasons, please wait 5 minutes before you try again."),
|
'rate_limit': _("For security reasons, please wait 5 minutes before you try again."),
|
||||||
|
|||||||
@@ -37,6 +37,16 @@ class BaseMediaType:
|
|||||||
def verbose_name(self):
|
def verbose_name(self):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def icon(self):
|
||||||
|
"""
|
||||||
|
This can be:
|
||||||
|
|
||||||
|
- The name of a Font Awesome icon to represent this channel type.
|
||||||
|
- The name of a SVG icon file that is resolvable through the static file system. We recommend to design for a size of 18x14 pixels.
|
||||||
|
"""
|
||||||
|
return "circle"
|
||||||
|
|
||||||
def generate_identifier(self, organizer):
|
def generate_identifier(self, organizer):
|
||||||
if self.medium_created_by_server:
|
if self.medium_created_by_server:
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
@@ -59,6 +69,7 @@ class BaseMediaType:
|
|||||||
class BarcodePlainMediaType(BaseMediaType):
|
class BarcodePlainMediaType(BaseMediaType):
|
||||||
identifier = 'barcode'
|
identifier = 'barcode'
|
||||||
verbose_name = _('Barcode / QR-Code')
|
verbose_name = _('Barcode / QR-Code')
|
||||||
|
icon = 'qrcode'
|
||||||
medium_created_by_server = True
|
medium_created_by_server = True
|
||||||
supports_giftcard = False
|
supports_giftcard = False
|
||||||
supports_orderposition = True
|
supports_orderposition = True
|
||||||
@@ -75,6 +86,7 @@ class BarcodePlainMediaType(BaseMediaType):
|
|||||||
class NfcUidMediaType(BaseMediaType):
|
class NfcUidMediaType(BaseMediaType):
|
||||||
identifier = 'nfc_uid'
|
identifier = 'nfc_uid'
|
||||||
verbose_name = _('NFC UID-based')
|
verbose_name = _('NFC UID-based')
|
||||||
|
icon = 'pretixbase/img/media/nfc_uid.svg'
|
||||||
medium_created_by_server = False
|
medium_created_by_server = False
|
||||||
supports_giftcard = True
|
supports_giftcard = True
|
||||||
supports_orderposition = False
|
supports_orderposition = False
|
||||||
@@ -114,6 +126,7 @@ class NfcUidMediaType(BaseMediaType):
|
|||||||
class NfcMf0aesMediaType(BaseMediaType):
|
class NfcMf0aesMediaType(BaseMediaType):
|
||||||
identifier = 'nfc_mf0aes'
|
identifier = 'nfc_mf0aes'
|
||||||
verbose_name = 'NFC Mifare Ultralight AES'
|
verbose_name = 'NFC Mifare Ultralight AES'
|
||||||
|
icon = 'pretixbase/img/media/nfc_secure.svg'
|
||||||
medium_created_by_server = False
|
medium_created_by_server = False
|
||||||
supports_giftcard = True
|
supports_giftcard = True
|
||||||
supports_orderposition = False
|
supports_orderposition = False
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ class Migration(migrations.Migration):
|
|||||||
('password', models.CharField(verbose_name='password', max_length=128)),
|
('password', models.CharField(verbose_name='password', max_length=128)),
|
||||||
('last_login', models.DateTimeField(verbose_name='last login', blank=True, null=True)),
|
('last_login', models.DateTimeField(verbose_name='last login', blank=True, null=True)),
|
||||||
('is_superuser', models.BooleanField(verbose_name='superuser status', default=False, help_text='Designates that this user has all permissions without explicitly assigning them.')),
|
('is_superuser', models.BooleanField(verbose_name='superuser status', default=False, help_text='Designates that this user has all permissions without explicitly assigning them.')),
|
||||||
('email', models.EmailField(max_length=191, blank=True, unique=True, verbose_name='E-mail', null=True,
|
('email', models.EmailField(max_length=191, blank=True, unique=True, verbose_name='Email', null=True,
|
||||||
db_index=True)),
|
db_index=True)),
|
||||||
('givenname', models.CharField(verbose_name='Given name', max_length=255, blank=True, null=True)),
|
('givenname', models.CharField(verbose_name='Given name', max_length=255, blank=True, null=True)),
|
||||||
('familyname', models.CharField(verbose_name='Family name', max_length=255, blank=True, null=True)),
|
('familyname', models.CharField(verbose_name='Family name', max_length=255, blank=True, null=True)),
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ class Migration(migrations.Migration):
|
|||||||
('password', models.CharField(max_length=128, verbose_name='password')),
|
('password', models.CharField(max_length=128, verbose_name='password')),
|
||||||
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
|
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
|
||||||
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
|
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
|
||||||
('email', models.EmailField(blank=True, db_index=True, max_length=254, null=True, unique=True, verbose_name='E-mail')),
|
('email', models.EmailField(blank=True, db_index=True, max_length=254, null=True, unique=True, verbose_name='Email')),
|
||||||
('givenname', models.CharField(blank=True, max_length=255, null=True, verbose_name='Given name')),
|
('givenname', models.CharField(blank=True, max_length=255, null=True, verbose_name='Given name')),
|
||||||
('familyname', models.CharField(blank=True, max_length=255, null=True, verbose_name='Family name')),
|
('familyname', models.CharField(blank=True, max_length=255, null=True, verbose_name='Family name')),
|
||||||
('is_active', models.BooleanField(default=True, verbose_name='Is active')),
|
('is_active', models.BooleanField(default=True, verbose_name='Is active')),
|
||||||
@@ -232,7 +232,7 @@ class Migration(migrations.Migration):
|
|||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
('code', models.CharField(max_length=16, verbose_name='Order code')),
|
('code', models.CharField(max_length=16, verbose_name='Order code')),
|
||||||
('status', models.CharField(choices=[('n', 'pending'), ('p', 'paid'), ('e', 'expired'), ('c', 'cancelled'), ('r', 'refunded')], max_length=3, verbose_name='Status')),
|
('status', models.CharField(choices=[('n', 'pending'), ('p', 'paid'), ('e', 'expired'), ('c', 'cancelled'), ('r', 'refunded')], max_length=3, verbose_name='Status')),
|
||||||
('email', models.EmailField(blank=True, max_length=254, null=True, verbose_name='E-mail')),
|
('email', models.EmailField(blank=True, max_length=254, null=True, verbose_name='Email')),
|
||||||
('locale', models.CharField(blank=True, max_length=32, null=True, verbose_name='Locale')),
|
('locale', models.CharField(blank=True, max_length=32, null=True, verbose_name='Locale')),
|
||||||
('secret', models.CharField(default=pretix.base.models.orders.generate_secret, max_length=32)),
|
('secret', models.CharField(default=pretix.base.models.orders.generate_secret, max_length=32)),
|
||||||
('datetime', models.DateTimeField(verbose_name='Date')),
|
('datetime', models.DateTimeField(verbose_name='Date')),
|
||||||
|
|||||||
@@ -187,7 +187,7 @@ class Migration(migrations.Migration):
|
|||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
('code', models.CharField(max_length=16, verbose_name='Order code')),
|
('code', models.CharField(max_length=16, verbose_name='Order code')),
|
||||||
('status', models.CharField(choices=[('n', 'pending'), ('p', 'paid'), ('e', 'expired'), ('c', 'cancelled'), ('r', 'refunded')], max_length=3, verbose_name='Status')),
|
('status', models.CharField(choices=[('n', 'pending'), ('p', 'paid'), ('e', 'expired'), ('c', 'cancelled'), ('r', 'refunded')], max_length=3, verbose_name='Status')),
|
||||||
('email', models.EmailField(blank=True, max_length=254, null=True, verbose_name='E-mail')),
|
('email', models.EmailField(blank=True, max_length=254, null=True, verbose_name='Email')),
|
||||||
('locale', models.CharField(blank=True, max_length=32, null=True, verbose_name='Locale')),
|
('locale', models.CharField(blank=True, max_length=32, null=True, verbose_name='Locale')),
|
||||||
('secret', models.CharField(default=pretix.base.models.orders.generate_secret, max_length=32)),
|
('secret', models.CharField(default=pretix.base.models.orders.generate_secret, max_length=32)),
|
||||||
('datetime', models.DateTimeField(verbose_name='Date')),
|
('datetime', models.DateTimeField(verbose_name='Date')),
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class Migration(migrations.Migration):
|
|||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
('created', models.DateTimeField(auto_now_add=True, verbose_name='On waiting list since')),
|
('created', models.DateTimeField(auto_now_add=True, verbose_name='On waiting list since')),
|
||||||
('email', models.EmailField(max_length=254, verbose_name='E-mail address')),
|
('email', models.EmailField(max_length=254, verbose_name='Email address')),
|
||||||
('locale', models.CharField(default='en', max_length=190)),
|
('locale', models.CharField(default='en', max_length=190)),
|
||||||
('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='waitinglistentries', to='pretixbase.Event', verbose_name='Event')),
|
('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='waitinglistentries', to='pretixbase.Event', verbose_name='Event')),
|
||||||
('item', models.ForeignKey(help_text='The product the user waits for.', on_delete=django.db.models.deletion.CASCADE, related_name='waitinglistentries', to='pretixbase.Item', verbose_name='Product')),
|
('item', models.ForeignKey(help_text='The product the user waits for.', on_delete=django.db.models.deletion.CASCADE, related_name='waitinglistentries', to='pretixbase.Item', verbose_name='Product')),
|
||||||
|
|||||||
+1
-1
@@ -35,7 +35,7 @@ class Migration(migrations.Migration):
|
|||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
('created', models.DateTimeField(auto_now_add=True, verbose_name='On waiting list since')),
|
('created', models.DateTimeField(auto_now_add=True, verbose_name='On waiting list since')),
|
||||||
('email', models.EmailField(max_length=254, verbose_name='E-mail address')),
|
('email', models.EmailField(max_length=254, verbose_name='Email address')),
|
||||||
('locale', models.CharField(default='en', max_length=190)),
|
('locale', models.CharField(default='en', max_length=190)),
|
||||||
('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='waitinglistentries', to='pretixbase.Event', verbose_name='Event')),
|
('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='waitinglistentries', to='pretixbase.Event', verbose_name='Event')),
|
||||||
('item', models.ForeignKey(help_text='The product the user waits for.', on_delete=django.db.models.deletion.CASCADE, related_name='waitinglistentries', to='pretixbase.Item', verbose_name='Product')),
|
('item', models.ForeignKey(help_text='The product the user waits for.', on_delete=django.db.models.deletion.CASCADE, related_name='waitinglistentries', to='pretixbase.Item', verbose_name='Product')),
|
||||||
|
|||||||
+1
-1
@@ -163,7 +163,7 @@ class Migration(migrations.Migration):
|
|||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
('action_type', models.CharField(max_length=255)),
|
('action_type', models.CharField(max_length=255)),
|
||||||
('method', models.CharField(choices=[('mail', 'E-mail')], max_length=255)),
|
('method', models.CharField(choices=[('mail', 'Email')], max_length=255)),
|
||||||
('event', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE,
|
('event', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE,
|
||||||
to='pretixbase.Event')),
|
to='pretixbase.Event')),
|
||||||
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ class Migration(migrations.Migration):
|
|||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
('action_type', models.CharField(max_length=255)),
|
('action_type', models.CharField(max_length=255)),
|
||||||
('method', models.CharField(choices=[('mail', 'E-mail')], max_length=255)),
|
('method', models.CharField(choices=[('mail', 'Email')], max_length=255)),
|
||||||
('event', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='pretixbase.Event')),
|
('event', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='pretixbase.Event')),
|
||||||
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||||
('enabled', models.BooleanField(default=True)),
|
('enabled', models.BooleanField(default=True)),
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ from pretix.base.signals import order_import_columns
|
|||||||
|
|
||||||
class EmailColumn(ImportColumn):
|
class EmailColumn(ImportColumn):
|
||||||
identifier = 'email'
|
identifier = 'email'
|
||||||
verbose_name = gettext_lazy('E-mail address')
|
verbose_name = gettext_lazy('Email address')
|
||||||
|
|
||||||
def clean(self, value, previous_values):
|
def clean(self, value, previous_values):
|
||||||
if value:
|
if value:
|
||||||
@@ -322,7 +322,7 @@ class AttendeeNamePart(ImportColumn):
|
|||||||
|
|
||||||
class AttendeeEmail(ImportColumn):
|
class AttendeeEmail(ImportColumn):
|
||||||
identifier = 'attendee_email'
|
identifier = 'attendee_email'
|
||||||
verbose_name = gettext_lazy('Attendee e-mail address')
|
verbose_name = gettext_lazy('Attendee email address')
|
||||||
|
|
||||||
def clean(self, value, previous_values):
|
def clean(self, value, previous_values):
|
||||||
if value:
|
if value:
|
||||||
|
|||||||
@@ -241,7 +241,7 @@ class User(AbstractBaseUser, PermissionsMixin, LoggingMixin):
|
|||||||
REQUIRED_FIELDS = []
|
REQUIRED_FIELDS = []
|
||||||
|
|
||||||
email = models.EmailField(unique=True, db_index=True, null=True, blank=True,
|
email = models.EmailField(unique=True, db_index=True, null=True, blank=True,
|
||||||
verbose_name=_('E-mail'), max_length=190)
|
verbose_name=_('Email'), max_length=190)
|
||||||
fullname = models.CharField(max_length=255, blank=True, null=True,
|
fullname = models.CharField(max_length=255, blank=True, null=True,
|
||||||
verbose_name=_('Full name'))
|
verbose_name=_('Full name'))
|
||||||
is_active = models.BooleanField(default=True,
|
is_active = models.BooleanField(default=True,
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ class Customer(LoggedModel):
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
email = models.EmailField(db_index=True, null=True, blank=False, verbose_name=_('E-mail'), max_length=190)
|
email = models.EmailField(db_index=True, null=True, blank=False, verbose_name=_('Email'), max_length=190)
|
||||||
phone = PhoneNumberField(null=True, blank=True, verbose_name=_('Phone number'))
|
phone = PhoneNumberField(null=True, blank=True, verbose_name=_('Phone number'))
|
||||||
password = models.CharField(verbose_name=_('Password'), max_length=128)
|
password = models.CharField(verbose_name=_('Password'), max_length=128)
|
||||||
name_cached = models.CharField(max_length=255, verbose_name=_('Full name'), blank=True)
|
name_cached = models.CharField(max_length=255, verbose_name=_('Full name'), blank=True)
|
||||||
@@ -392,7 +392,7 @@ class CustomerSSOClient(LoggedModel):
|
|||||||
SCOPE_CHOICES = (
|
SCOPE_CHOICES = (
|
||||||
('openid', _('OpenID Connect access (required)')),
|
('openid', _('OpenID Connect access (required)')),
|
||||||
('profile', _('Profile data (name, addresses)')),
|
('profile', _('Profile data (name, addresses)')),
|
||||||
('email', _('E-mail address')),
|
('email', _('Email address')),
|
||||||
('phone', _('Phone number')),
|
('phone', _('Phone number')),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ class NotificationSetting(models.Model):
|
|||||||
:type enabled: bool
|
:type enabled: bool
|
||||||
"""
|
"""
|
||||||
CHANNELS = (
|
CHANNELS = (
|
||||||
('mail', _('E-mail')),
|
('mail', _('Email')),
|
||||||
)
|
)
|
||||||
user = models.ForeignKey('User', on_delete=models.CASCADE,
|
user = models.ForeignKey('User', on_delete=models.CASCADE,
|
||||||
related_name='notification_settings')
|
related_name='notification_settings')
|
||||||
|
|||||||
@@ -242,7 +242,7 @@ class Order(LockModel, LoggedModel):
|
|||||||
)
|
)
|
||||||
email = models.EmailField(
|
email = models.EmailField(
|
||||||
null=True, blank=True,
|
null=True, blank=True,
|
||||||
verbose_name=_('E-mail')
|
verbose_name=_('Email')
|
||||||
)
|
)
|
||||||
phone = PhoneNumberField(
|
phone = PhoneNumberField(
|
||||||
null=True, blank=True,
|
null=True, blank=True,
|
||||||
@@ -317,7 +317,7 @@ class Order(LockModel, LoggedModel):
|
|||||||
)
|
)
|
||||||
email_known_to_work = models.BooleanField(
|
email_known_to_work = models.BooleanField(
|
||||||
default=False,
|
default=False,
|
||||||
verbose_name=_('E-mail address verified')
|
verbose_name=_('Email address verified')
|
||||||
)
|
)
|
||||||
invoice_dirty = models.BooleanField(
|
invoice_dirty = models.BooleanField(
|
||||||
# Invoice needs to be re-issued when the order is paid again
|
# Invoice needs to be re-issued when the order is paid again
|
||||||
@@ -3204,9 +3204,9 @@ class InvoiceAddress(models.Model):
|
|||||||
company = models.CharField(max_length=255, blank=True, verbose_name=_('Company name'))
|
company = models.CharField(max_length=255, blank=True, verbose_name=_('Company name'))
|
||||||
name_cached = models.CharField(max_length=255, verbose_name=_('Full name'), blank=True)
|
name_cached = models.CharField(max_length=255, verbose_name=_('Full name'), blank=True)
|
||||||
name_parts = models.JSONField(default=dict)
|
name_parts = models.JSONField(default=dict)
|
||||||
street = models.TextField(verbose_name=_('Address'), blank=False)
|
street = models.TextField(verbose_name=_('Address'), blank=True)
|
||||||
zipcode = models.CharField(max_length=30, verbose_name=_('ZIP code'), blank=False)
|
zipcode = models.CharField(max_length=30, verbose_name=_('ZIP code'), blank=True)
|
||||||
city = models.CharField(max_length=255, verbose_name=_('City'), blank=False)
|
city = models.CharField(max_length=255, verbose_name=_('City'), blank=True)
|
||||||
country_old = models.CharField(max_length=255, verbose_name=_('Country'), blank=False)
|
country_old = models.CharField(max_length=255, verbose_name=_('Country'), blank=False)
|
||||||
country = FastCountryField(verbose_name=_('Country'), blank=False, blank_label=_('Select country'),
|
country = FastCountryField(verbose_name=_('Country'), blank=False, blank_label=_('Select country'),
|
||||||
countries=CachedCountries)
|
countries=CachedCountries)
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ class WaitingListEntry(LoggedModel):
|
|||||||
blank=True, default=dict
|
blank=True, default=dict
|
||||||
)
|
)
|
||||||
email = models.EmailField(
|
email = models.EmailField(
|
||||||
verbose_name=_("E-mail address")
|
verbose_name=_("Email address")
|
||||||
)
|
)
|
||||||
phone = PhoneNumberField(
|
phone = PhoneNumberField(
|
||||||
null=True, blank=True,
|
null=True, blank=True,
|
||||||
|
|||||||
@@ -315,7 +315,7 @@ def mail(email: Union[str, Sequence[str]], subject: str, template: Union[str, La
|
|||||||
body_html = renderer.render(content_plain, signature, raw_subject, order, position)
|
body_html = renderer.render(content_plain, signature, raw_subject, order, position)
|
||||||
else:
|
else:
|
||||||
# Backwards compatibility
|
# Backwards compatibility
|
||||||
warnings.warn('E-mail renderer called without position argument because position argument is not '
|
warnings.warn('Email renderer called without position argument because position argument is not '
|
||||||
'supported.',
|
'supported.',
|
||||||
DeprecationWarning)
|
DeprecationWarning)
|
||||||
body_html = renderer.render(content_plain, signature, raw_subject, order)
|
body_html = renderer.render(content_plain, signature, raw_subject, order)
|
||||||
|
|||||||
@@ -287,9 +287,9 @@ class PhoneNumberShredder(BaseDataShredder):
|
|||||||
|
|
||||||
|
|
||||||
class EmailAddressShredder(BaseDataShredder):
|
class EmailAddressShredder(BaseDataShredder):
|
||||||
verbose_name = _('E-mails')
|
verbose_name = _('Emails')
|
||||||
identifier = 'order_emails'
|
identifier = 'order_emails'
|
||||||
description = _('This will remove all e-mail addresses from orders and attendees, as well as logged email '
|
description = _('This will remove all email addresses from orders and attendees, as well as logged email '
|
||||||
'contents. This will also remove the association to customer accounts.')
|
'contents. This will also remove the association to customer accounts.')
|
||||||
|
|
||||||
def generate_files(self) -> List[Tuple[str, str, str]]:
|
def generate_files(self) -> List[Tuple[str, str, str]]:
|
||||||
|
|||||||
@@ -22,16 +22,30 @@
|
|||||||
import pycountry
|
import pycountry
|
||||||
from django.http import JsonResponse
|
from django.http import JsonResponse
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
def states(request):
|
def states(request):
|
||||||
cc = request.GET.get("country", "DE")
|
cc = request.GET.get("country", "DE")
|
||||||
|
info = {
|
||||||
|
'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},
|
||||||
|
'vat_id': {'visible': cc in VAT_ID_COUNTRIES, 'required': False},
|
||||||
|
}
|
||||||
if cc not in COUNTRIES_WITH_STATE_IN_ADDRESS:
|
if cc not in COUNTRIES_WITH_STATE_IN_ADDRESS:
|
||||||
return JsonResponse({'data': []})
|
return JsonResponse({'data': [], **info, })
|
||||||
types, form = COUNTRIES_WITH_STATE_IN_ADDRESS[cc]
|
types, form = COUNTRIES_WITH_STATE_IN_ADDRESS[cc]
|
||||||
statelist = [s for s in pycountry.subdivisions.get(country_code=cc) if s.type in types]
|
statelist = [s for s in pycountry.subdivisions.get(country_code=cc) if s.type in types]
|
||||||
return JsonResponse({'data': [
|
return JsonResponse({
|
||||||
{'name': s.name, 'code': s.code[3:]}
|
'data': [
|
||||||
for s in sorted(statelist, key=lambda s: s.name)
|
{'name': s.name, 'code': s.code[3:]}
|
||||||
]})
|
for s in sorted(statelist, key=lambda s: s.name)
|
||||||
|
],
|
||||||
|
**info,
|
||||||
|
})
|
||||||
|
|||||||
@@ -549,7 +549,7 @@ class EventOrderExpertFilterForm(EventOrderFilterForm):
|
|||||||
)
|
)
|
||||||
email = forms.CharField(
|
email = forms.CharField(
|
||||||
required=False,
|
required=False,
|
||||||
label=_('E-mail address')
|
label=_('Email address')
|
||||||
)
|
)
|
||||||
comment = forms.CharField(
|
comment = forms.CharField(
|
||||||
required=False,
|
required=False,
|
||||||
@@ -563,7 +563,7 @@ class EventOrderExpertFilterForm(EventOrderFilterForm):
|
|||||||
email_known_to_work = forms.NullBooleanField(
|
email_known_to_work = forms.NullBooleanField(
|
||||||
required=False,
|
required=False,
|
||||||
widget=FilterNullBooleanSelect,
|
widget=FilterNullBooleanSelect,
|
||||||
label=_('E-mail address verified'),
|
label=_('Email address verified'),
|
||||||
)
|
)
|
||||||
total = forms.DecimalField(
|
total = forms.DecimalField(
|
||||||
localize=True,
|
localize=True,
|
||||||
@@ -648,7 +648,7 @@ class EventOrderExpertFilterForm(EventOrderFilterForm):
|
|||||||
)
|
)
|
||||||
self.fields['attendee_email'] = forms.CharField(
|
self.fields['attendee_email'] = forms.CharField(
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Attendee e-mail address')
|
label=_('Attendee email address')
|
||||||
)
|
)
|
||||||
self.fields['attendee_address_company'] = forms.CharField(
|
self.fields['attendee_address_company'] = forms.CharField(
|
||||||
required=False,
|
required=False,
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ class UpdateSettingsForm(SettingsForm):
|
|||||||
)
|
)
|
||||||
update_check_email = forms.EmailField(
|
update_check_email = forms.EmailField(
|
||||||
required=False,
|
required=False,
|
||||||
label=_("E-mail notifications"),
|
label=_("Email notifications"),
|
||||||
help_text=_("We will notify you at this address if we detect that a new update is available. This "
|
help_text=_("We will notify you at this address if we detect that a new update is available. This "
|
||||||
"address will not be transmitted to pretix.eu, the emails will be sent by this server "
|
"address will not be transmitted to pretix.eu, the emails will be sent by this server "
|
||||||
"locally.")
|
"locally.")
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ class StaffSessionForm(forms.ModelForm):
|
|||||||
|
|
||||||
class UserEditForm(forms.ModelForm):
|
class UserEditForm(forms.ModelForm):
|
||||||
error_messages = {
|
error_messages = {
|
||||||
'duplicate_identifier': _("There already is an account associated with this e-mail address. "
|
'duplicate_identifier': _("There already is an account associated with this email address. "
|
||||||
"Please choose a different one."),
|
"Please choose a different one."),
|
||||||
'pw_mismatch': _("Please enter the same password twice"),
|
'pw_mismatch': _("Please enter the same password twice"),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ def get_event_navigation(request: HttpRequest):
|
|||||||
'active': url.url_name == 'event.settings.tickets',
|
'active': url.url_name == 'event.settings.tickets',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'label': _('E-mail'),
|
'label': _('Email'),
|
||||||
'url': reverse('control:event.settings.mail', kwargs={
|
'url': reverse('control:event.settings.mail', kwargs={
|
||||||
'event': request.event.slug,
|
'event': request.event.slug,
|
||||||
'organizer': request.event.organizer.slug,
|
'organizer': request.event.organizer.slug,
|
||||||
@@ -132,16 +132,6 @@ def get_event_navigation(request: HttpRequest):
|
|||||||
'icon': 'wrench',
|
'icon': 'wrench',
|
||||||
'children': event_settings
|
'children': event_settings
|
||||||
})
|
})
|
||||||
if request.event.has_subevents:
|
|
||||||
nav.append({
|
|
||||||
'label': pgettext_lazy('subevent', 'Dates'),
|
|
||||||
'url': reverse('control:event.subevents', kwargs={
|
|
||||||
'event': request.event.slug,
|
|
||||||
'organizer': request.event.organizer.slug,
|
|
||||||
}),
|
|
||||||
'active': ('event.subevent' in url.url_name),
|
|
||||||
'icon': 'calendar',
|
|
||||||
})
|
|
||||||
|
|
||||||
if 'can_change_items' in request.eventpermset:
|
if 'can_change_items' in request.eventpermset:
|
||||||
nav.append({
|
nav.append({
|
||||||
@@ -197,6 +187,18 @@ def get_event_navigation(request: HttpRequest):
|
|||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if 'can_change_event_settings' in request.eventpermset:
|
||||||
|
if request.event.has_subevents:
|
||||||
|
nav.append({
|
||||||
|
'label': pgettext_lazy('subevent', 'Dates'),
|
||||||
|
'url': reverse('control:event.subevents', kwargs={
|
||||||
|
'event': request.event.slug,
|
||||||
|
'organizer': request.event.organizer.slug,
|
||||||
|
}),
|
||||||
|
'active': ('event.subevent' in url.url_name),
|
||||||
|
'icon': 'calendar',
|
||||||
|
})
|
||||||
|
|
||||||
if 'can_view_orders' in request.eventpermset:
|
if 'can_view_orders' in request.eventpermset:
|
||||||
children = [
|
children = [
|
||||||
{
|
{
|
||||||
@@ -496,7 +498,7 @@ def get_organizer_navigation(request):
|
|||||||
'active': url.url_name.startswith('organizer.propert'),
|
'active': url.url_name.startswith('organizer.propert'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'label': _('E-mail'),
|
'label': _('Email'),
|
||||||
'url': reverse('control:organizer.settings.mail', kwargs={
|
'url': reverse('control:organizer.settings.mail', kwargs={
|
||||||
'organizer': request.organizer.slug,
|
'organizer': request.organizer.slug,
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -61,6 +61,7 @@
|
|||||||
<script type="text/javascript" src="{% static "fileupload/jquery.fileupload.js" %}"></script>
|
<script type="text/javascript" src="{% static "fileupload/jquery.fileupload.js" %}"></script>
|
||||||
<script type="text/javascript" src="{% static "lightbox/js/lightbox.js" %}"></script>
|
<script type="text/javascript" src="{% static "lightbox/js/lightbox.js" %}"></script>
|
||||||
<script type="text/javascript" src="{% static "are-you-sure/jquery.are-you-sure.js" %}"></script>
|
<script type="text/javascript" src="{% static "are-you-sure/jquery.are-you-sure.js" %}"></script>
|
||||||
|
<script type="text/javascript" src="{% static "pretixbase/js/addressform.js" %}"></script>
|
||||||
{% endcompress %}
|
{% endcompress %}
|
||||||
{{ html_head|safe }}
|
{{ html_head|safe }}
|
||||||
|
|
||||||
|
|||||||
@@ -127,6 +127,7 @@
|
|||||||
<strong>
|
<strong>
|
||||||
<a href="{% url "control:event.order" event=request.event.slug organizer=request.event.organizer.slug code=c.position.order.code %}">{{ c.position.order.code }}</a>-{{ c.position.positionid }}
|
<a href="{% url "control:event.order" event=request.event.slug organizer=request.event.organizer.slug code=c.position.order.code %}">{{ c.position.order.code }}</a>-{{ c.position.positionid }}
|
||||||
</strong>
|
</strong>
|
||||||
|
{% include "pretixcontrol/checkin/fragment_checkin_source_type.html" with source_type=c.raw_source_type %}
|
||||||
{% if c.position.attendee_name %}
|
{% if c.position.attendee_name %}
|
||||||
<br>
|
<br>
|
||||||
<small>
|
<small>
|
||||||
@@ -143,7 +144,7 @@
|
|||||||
</small>
|
</small>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<span class="fa fa-qrcode fa-fw"></span>
|
{% include "pretixcontrol/checkin/fragment_checkin_source_type.html" with source_type=c.raw_source_type %}
|
||||||
<span title="{{ c.raw_barcode }}">
|
<span title="{{ c.raw_barcode }}">
|
||||||
{{ c.raw_barcode|slice:":16" }}{% if c.raw_barcode|length > 16 %}…{% endif %}
|
{{ c.raw_barcode|slice:":16" }}{% if c.raw_barcode|length > 16 %}…{% endif %}
|
||||||
<button type="button" class="btn btn-xs btn-link btn-clipboard" data-clipboard-text="{{ c.raw_barcode }}">
|
<button type="button" class="btn btn-xs btn-link btn-clipboard" data-clipboard-text="{{ c.raw_barcode }}">
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
{% load i18n %}
|
||||||
|
{% load static %}
|
||||||
|
{% load getitem %}
|
||||||
|
|
||||||
|
{% if source_type %}
|
||||||
|
{% with media_types|getitem:source_type as media_type %}
|
||||||
|
{% if "." in media_type.icon %}
|
||||||
|
<img src="{% static media_type.icon %}" class="fa-like-image"
|
||||||
|
data-toggle="tooltip" title="{{ media_type.verbose_name }}">
|
||||||
|
{% else %}
|
||||||
|
<span class="fa fa-fw fa-{{ media_type.icon }} text-muted"
|
||||||
|
data-toggle="tooltip" title="{{ media_type.verbose_name }}"></span>
|
||||||
|
{% endif %}
|
||||||
|
{% endwith %}
|
||||||
|
{% endif %}
|
||||||
@@ -185,6 +185,7 @@
|
|||||||
<span class="fa fa-magic text-muted"
|
<span class="fa fa-magic text-muted"
|
||||||
data-toggle="tooltip" title="{% trans "Checked in automatically" %}"></span>
|
data-toggle="tooltip" title="{% trans "Checked in automatically" %}"></span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% include "pretixcontrol/checkin/fragment_checkin_source_type.html" with source_type=e.last_entry_source_type %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
{% load static %}
|
{% load static %}
|
||||||
{% block title %}{% trans "Organizer" %}{% endblock %}
|
{% block title %}{% trans "Organizer" %}{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>{% trans "E-mail sending" %}</h1>
|
<h1>{% trans "Email sending" %}</h1>
|
||||||
<form action="" method="post" class="form-horizontal">
|
<form action="" method="post" class="form-horizontal">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<div class="panel-group" id="email">
|
<div class="panel-group" id="email">
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
<div class="panel-body form-horizontal">
|
<div class="panel-body form-horizontal">
|
||||||
<p>
|
<p>
|
||||||
{% blocktrans trimmed %}
|
{% blocktrans trimmed %}
|
||||||
E-mails will be sent through the system's default server. They will show the following
|
Emails will be sent through the system's default server. They will show the following
|
||||||
sender information:
|
sender information:
|
||||||
{% endblocktrans %}
|
{% endblocktrans %}
|
||||||
</p>
|
</p>
|
||||||
@@ -62,7 +62,7 @@
|
|||||||
<div class="panel-body form-horizontal">
|
<div class="panel-body form-horizontal">
|
||||||
<p>
|
<p>
|
||||||
{% blocktrans trimmed %}
|
{% blocktrans trimmed %}
|
||||||
E-mails will be sent through the system's default server but with your own sender
|
Emails will be sent through the system's default server but with your own sender
|
||||||
address.
|
address.
|
||||||
This will make your emails look more personalized and coming directly from you, but it
|
This will make your emails look more personalized and coming directly from you, but it
|
||||||
also might require some extra steps to ensure good deliverability.
|
also might require some extra steps to ensure good deliverability.
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
{% load static %}
|
{% load static %}
|
||||||
{% block title %}{% trans "Organizer" %}{% endblock %}
|
{% block title %}{% trans "Organizer" %}{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>{% trans "E-mail sending" %}</h1>
|
<h1>{% trans "Email sending" %}</h1>
|
||||||
<form action="" method="post" class="form-horizontal">
|
<form action="" method="post" class="form-horizontal">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{% for k, v in request.POST.items %}
|
{% for k, v in request.POST.items %}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
{% load static %}
|
{% load static %}
|
||||||
{% block title %}{% trans "Organizer" %}{% endblock %}
|
{% block title %}{% trans "Organizer" %}{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>{% trans "E-mail sending" %}</h1>
|
<h1>{% trans "Email sending" %}</h1>
|
||||||
<form action="" method="post" class="form-horizontal">
|
<form action="" method="post" class="form-horizontal">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{% for k, v in request.POST.items %}
|
{% for k, v in request.POST.items %}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
{% load hierarkey_form %}
|
{% load hierarkey_form %}
|
||||||
{% load static %}
|
{% load static %}
|
||||||
{% block inside %}
|
{% block inside %}
|
||||||
<h1>{% trans "E-mail settings" %}</h1>
|
<h1>{% trans "Email settings" %}</h1>
|
||||||
<form action="" method="post" class="form-horizontal" enctype="multipart/form-data"
|
<form action="" method="post" class="form-horizontal" enctype="multipart/form-data"
|
||||||
mail-preview-url="{% url "control:event.settings.mail.preview" event=request.event.slug organizer=request.event.organizer.slug %}">
|
mail-preview-url="{% url "control:event.settings.mail.preview" event=request.event.slug organizer=request.event.organizer.slug %}">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
@@ -63,7 +63,7 @@
|
|||||||
{% bootstrap_field form.mail_attach_ical_description layout="control" %}
|
{% bootstrap_field form.mail_attach_ical_description layout="control" %}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>{% trans "E-mail design" %}</legend>
|
<legend>{% trans "Email design" %}</legend>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
{% for r in renderers.values %}
|
{% for r in renderers.values %}
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
@@ -84,7 +84,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>{% trans "E-mail content" %}</legend>
|
<legend>{% trans "Email content" %}</legend>
|
||||||
<h4>{% trans "Text" %}</h4>
|
<h4>{% trans "Text" %}</h4>
|
||||||
<div class="panel-group" id="questions_group">
|
<div class="panel-group" id="questions_group">
|
||||||
{% blocktrans asvar title_placed_order %}Placed order{% endblocktrans %}
|
{% blocktrans asvar title_placed_order %}Placed order{% endblocktrans %}
|
||||||
|
|||||||
@@ -67,7 +67,7 @@
|
|||||||
<h4>{% trans "Customer data (once per order)" %}</h4>
|
<h4>{% trans "Customer data (once per order)" %}</h4>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label col-md-3">
|
<label class="control-label col-md-3">
|
||||||
{% trans "E-mail" %}
|
{% trans "Email" %}
|
||||||
</label>
|
</label>
|
||||||
<div class="col-md-9">
|
<div class="col-md-9">
|
||||||
<div class="checkbox">
|
<div class="checkbox">
|
||||||
|
|||||||
@@ -46,11 +46,13 @@
|
|||||||
<div id="cp{{ pos.id }}">
|
<div id="cp{{ pos.id }}">
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
{% for form in forms %}
|
{% for form in forms %}
|
||||||
{% if form.pos.item != pos.item %}
|
<div class="profile-scope">
|
||||||
{# Add-Ons #}
|
{% if form.pos.item != pos.item %}
|
||||||
<legend>+ {{ form.pos.item }}</legend>
|
{# Add-Ons #}
|
||||||
{% endif %}
|
<legend>+ {{ form.pos.item }}</legend>
|
||||||
{% bootstrap_form form layout="control" %}
|
{% endif %}
|
||||||
|
{% bootstrap_form form layout="control" %}
|
||||||
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
{% if request.method == "POST" %}
|
{% if request.method == "POST" %}
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>{% trans "E-mail preview" %}</legend>
|
<legend>{% trans "Email preview" %}</legend>
|
||||||
<div class="tab-pane mail-preview-group">
|
<div class="tab-pane mail-preview-group">
|
||||||
<div lang="{{ order.locale }}" class="mail-preview">
|
<div lang="{{ order.locale }}" class="mail-preview">
|
||||||
<strong>{{ preview_output.subject }}</strong><br><br>
|
<strong>{{ preview_output.subject }}</strong><br><br>
|
||||||
|
|||||||
@@ -46,7 +46,7 @@
|
|||||||
{% trans "active" %}
|
{% trans "active" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</dd>
|
</dd>
|
||||||
<dt>{% trans "E-mail" %}</dt>
|
<dt>{% trans "Email" %}</dt>
|
||||||
<dd>
|
<dd>
|
||||||
{{ customer.email|default_if_none:"" }}
|
{{ customer.email|default_if_none:"" }}
|
||||||
{% if customer.email and not customer.provider %}
|
{% if customer.email and not customer.provider %}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block title %}{% trans "Organizer" %}{% endblock %}
|
{% block title %}{% trans "Organizer" %}{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>{% trans "E-mail settings" %}</h1>
|
<h1>{% trans "Email settings" %}</h1>
|
||||||
|
|
||||||
<form action="" method="post" class="form-horizontal" enctype="multipart/form-data"
|
<form action="" method="post" class="form-horizontal" enctype="multipart/form-data"
|
||||||
mail-preview-url="{% url "control:organizer.settings.mail.preview" organizer=request.organizer.slug %}">
|
mail-preview-url="{% url "control:organizer.settings.mail.preview" organizer=request.organizer.slug %}">
|
||||||
@@ -55,7 +55,7 @@
|
|||||||
{% bootstrap_field form.mail_bcc layout="control" %}
|
{% bootstrap_field form.mail_bcc layout="control" %}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>{% trans "E-mail content" %}</legend>
|
<legend>{% trans "Email content" %}</legend>
|
||||||
<div class="panel-group" id="questions_group">
|
<div class="panel-group" id="questions_group">
|
||||||
{% blocktrans asvar title_customer_registration %}Customer account registration{% endblocktrans %}
|
{% blocktrans asvar title_customer_registration %}Customer account registration{% endblocktrans %}
|
||||||
{% include "pretixcontrol/event/mail_settings_fragment.html" with pid="customer_registration" title=title_customer_registration items="mail_subject_customer_registration,mail_text_customer_registration" %}
|
{% include "pretixcontrol/event/mail_settings_fragment.html" with pid="customer_registration" title=title_customer_registration items="mail_subject_customer_registration,mail_text_customer_registration" %}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@
|
|||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{% trans "Notification type" %}</th>
|
<th>{% trans "Notification type" %}</th>
|
||||||
<th class="text-center">{% trans "E-Mail notification" %}</th>
|
<th class="text-center">{% trans "Email notification" %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
|||||||
@@ -39,7 +39,7 @@
|
|||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>
|
<th>
|
||||||
{% trans "E-mail address" %}
|
{% trans "Email address" %}
|
||||||
<a href="?{% url_replace request 'ordering' '-email' %}"><i class="fa fa-caret-down"></i></a>
|
<a href="?{% url_replace request 'ordering' '-email' %}"><i class="fa fa-caret-down"></i></a>
|
||||||
<a href="?{% url_replace request 'ordering' 'email' %}"><i class="fa fa-caret-up"></i></a>
|
<a href="?{% url_replace request 'ordering' 'email' %}"><i class="fa fa-caret-up"></i></a>
|
||||||
</th>
|
</th>
|
||||||
|
|||||||
@@ -343,7 +343,7 @@ class Forgot(TemplateView):
|
|||||||
logger.warning('Backend password reset for unregistered e-mail \"' + email + '\" requested.')
|
logger.warning('Backend password reset for unregistered e-mail \"' + email + '\" requested.')
|
||||||
|
|
||||||
except SendMailException:
|
except SendMailException:
|
||||||
logger.exception('Sending password reset e-mail to \"' + email + '\" failed.')
|
logger.exception('Sending password reset email to \"' + email + '\" failed.')
|
||||||
|
|
||||||
except RepeatedResetDenied:
|
except RepeatedResetDenied:
|
||||||
pass
|
pass
|
||||||
@@ -354,10 +354,10 @@ class Forgot(TemplateView):
|
|||||||
|
|
||||||
finally:
|
finally:
|
||||||
if has_redis:
|
if has_redis:
|
||||||
messages.info(request, _('If the address is registered to valid account, then we have sent you an e-mail containing further instructions. '
|
messages.info(request, _('If the address is registered to valid account, then we have sent you an email containing further instructions. '
|
||||||
'Please note that we will send at most one email every 24 hours.'))
|
'Please note that we will send at most one email every 24 hours.'))
|
||||||
else:
|
else:
|
||||||
messages.info(request, _('If the address is registered to valid account, then we have sent you an e-mail containing further instructions.'))
|
messages.info(request, _('If the address is registered to valid account, then we have sent you an email containing further instructions.'))
|
||||||
|
|
||||||
return redirect('control:auth.forgot')
|
return redirect('control:auth.forgot')
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ from django.views.generic import FormView, ListView, TemplateView
|
|||||||
from i18nfield.strings import LazyI18nString
|
from i18nfield.strings import LazyI18nString
|
||||||
|
|
||||||
from pretix.api.views.checkin import _redeem_process
|
from pretix.api.views.checkin import _redeem_process
|
||||||
|
from pretix.base.media import MEDIA_TYPES
|
||||||
from pretix.base.models import Checkin, Order, OrderPosition
|
from pretix.base.models import Checkin, Order, OrderPosition
|
||||||
from pretix.base.models.checkin import CheckinList
|
from pretix.base.models.checkin import CheckinList
|
||||||
from pretix.base.services.checkin import (
|
from pretix.base.services.checkin import (
|
||||||
@@ -81,9 +82,7 @@ class CheckInListQueryMixin:
|
|||||||
position_id=OuterRef('pk'),
|
position_id=OuterRef('pk'),
|
||||||
list_id=self.list.pk,
|
list_id=self.list.pk,
|
||||||
type=Checkin.TYPE_ENTRY
|
type=Checkin.TYPE_ENTRY
|
||||||
).order_by().values('position_id').annotate(
|
).order_by('-datetime').values('position_id')
|
||||||
m=Max('datetime')
|
|
||||||
).values('m')
|
|
||||||
cqs_exit = Checkin.objects.filter(
|
cqs_exit = Checkin.objects.filter(
|
||||||
position_id=OuterRef('pk'),
|
position_id=OuterRef('pk'),
|
||||||
list_id=self.list.pk,
|
list_id=self.list.pk,
|
||||||
@@ -103,7 +102,7 @@ class CheckInListQueryMixin:
|
|||||||
status_q,
|
status_q,
|
||||||
order__event=self.request.event,
|
order__event=self.request.event,
|
||||||
).annotate(
|
).annotate(
|
||||||
last_entry=Subquery(cqs),
|
last_entry=Subquery(cqs[:1].values('datetime')),
|
||||||
last_exit=Subquery(cqs_exit),
|
last_exit=Subquery(cqs_exit),
|
||||||
auto_checked_in=Exists(
|
auto_checked_in=Exists(
|
||||||
Checkin.objects.filter(
|
Checkin.objects.filter(
|
||||||
@@ -112,7 +111,8 @@ class CheckInListQueryMixin:
|
|||||||
list_id=self.list.pk,
|
list_id=self.list.pk,
|
||||||
auto_checked_in=True
|
auto_checked_in=True
|
||||||
)
|
)
|
||||||
)
|
),
|
||||||
|
last_entry_source_type=Subquery(cqs[:1].values('raw_source_type'))
|
||||||
).select_related(
|
).select_related(
|
||||||
'item', 'variation', 'order', 'addon_to'
|
'item', 'variation', 'order', 'addon_to'
|
||||||
).prefetch_related(
|
).prefetch_related(
|
||||||
@@ -157,6 +157,7 @@ class CheckInListShow(EventPermissionRequiredMixin, PaginationMixin, CheckInList
|
|||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
ctx = super().get_context_data(**kwargs)
|
ctx = super().get_context_data(**kwargs)
|
||||||
|
ctx['media_types'] = MEDIA_TYPES
|
||||||
ctx['checkinlist'] = self.list
|
ctx['checkinlist'] = self.list
|
||||||
if self.request.event.has_subevents:
|
if self.request.event.has_subevents:
|
||||||
ctx['seats'] = (
|
ctx['seats'] = (
|
||||||
@@ -497,6 +498,7 @@ class CheckinListView(EventPermissionRequiredMixin, PaginationMixin, ListView):
|
|||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
ctx = super().get_context_data()
|
ctx = super().get_context_data()
|
||||||
ctx['filter_form'] = self.filter_form
|
ctx['filter_form'] = self.filter_form
|
||||||
|
ctx['media_types'] = MEDIA_TYPES
|
||||||
return ctx
|
return ctx
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -807,7 +807,7 @@ class MailSettingsRendererPreview(MailSettingsPreview):
|
|||||||
r._csp_ignore = True
|
r._csp_ignore = True
|
||||||
return r
|
return r
|
||||||
else:
|
else:
|
||||||
raise Http404(_('Unknown e-mail renderer.'))
|
raise Http404(_('Unknown email renderer.'))
|
||||||
|
|
||||||
|
|
||||||
class TicketSettingsPreview(EventPermissionRequiredMixin, View):
|
class TicketSettingsPreview(EventPermissionRequiredMixin, View):
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ class UserResetView(AdministratorPermissionRequiredMixin, RecentAuthenticationRe
|
|||||||
|
|
||||||
self.object.log_action('pretix.control.auth.user.forgot_password.mail_sent',
|
self.object.log_action('pretix.control.auth.user.forgot_password.mail_sent',
|
||||||
user=request.user)
|
user=request.user)
|
||||||
messages.success(request, _('We sent out an e-mail containing further instructions.'))
|
messages.success(request, _('We sent out an email containing further instructions.'))
|
||||||
return redirect(self.get_success_url())
|
return redirect(self.get_success_url())
|
||||||
|
|
||||||
def get_success_url(self):
|
def get_success_url(self):
|
||||||
|
|||||||
@@ -304,7 +304,7 @@ class WaitingListView(EventPermissionRequiredMixin, WaitingListQuerySetMixin, Pa
|
|||||||
writer = csv.writer(output, quoting=csv.QUOTE_NONNUMERIC, delimiter=",")
|
writer = csv.writer(output, quoting=csv.QUOTE_NONNUMERIC, delimiter=",")
|
||||||
|
|
||||||
headers = [
|
headers = [
|
||||||
_('Name'), _('E-mail address'), _('Phone number'), _('Product'), _('On list since'), _('Status'), _('Voucher code'),
|
_('Name'), _('Email address'), _('Phone number'), _('Product'), _('On list since'), _('Status'), _('Voucher code'),
|
||||||
_('Language'), _('Priority')
|
_('Language'), _('Priority')
|
||||||
]
|
]
|
||||||
if self.request.event.has_subevents:
|
if self.request.event.has_subevents:
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -198,6 +198,7 @@ Mitgliedschafts
|
|||||||
Mitgliedschaftsdauer
|
Mitgliedschaftsdauer
|
||||||
min
|
min
|
||||||
Mo
|
Mo
|
||||||
|
MobilePay
|
||||||
MOTO
|
MOTO
|
||||||
Multibanco
|
Multibanco
|
||||||
MwSt
|
MwSt
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -198,6 +198,7 @@ Mitgliedschafts
|
|||||||
Mitgliedschaftsdauer
|
Mitgliedschaftsdauer
|
||||||
min
|
min
|
||||||
Mo
|
Mo
|
||||||
|
MobilePay
|
||||||
MOTO
|
MOTO
|
||||||
Multibanco
|
Multibanco
|
||||||
MwSt
|
MwSt
|
||||||
|
|||||||
+285
-288
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2024-11-08 13:45+0000\n"
|
"POT-Creation-Date: 2024-11-18 15:30+0000\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@ msgstr ""
|
|||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2024-11-08 13:45+0000\n"
|
"POT-Creation-Date: 2024-11-08 13:45+0000\n"
|
||||||
"PO-Revision-Date: 2024-11-13 21:00+0000\n"
|
"PO-Revision-Date: 2024-11-18 15:48+0000\n"
|
||||||
"Last-Translator: CVZ-es <damien.bremont@casadevelazquez.org>\n"
|
"Last-Translator: CVZ-es <damien.bremont@casadevelazquez.org>\n"
|
||||||
"Language-Team: Spanish <https://translate.pretix.eu/projects/pretix/"
|
"Language-Team: Spanish <https://translate.pretix.eu/projects/pretix/"
|
||||||
"pretix-js/es/>\n"
|
"pretix-js/es/>\n"
|
||||||
@@ -448,7 +448,7 @@ msgstr "Producto"
|
|||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:103
|
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:103
|
||||||
msgid "Product variation"
|
msgid "Product variation"
|
||||||
msgstr "Ver variaciones del producto"
|
msgstr "Variación del producto"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:107
|
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:107
|
||||||
msgid "Gate"
|
msgid "Gate"
|
||||||
@@ -645,7 +645,7 @@ msgstr ""
|
|||||||
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr "Consultar búsqueda"
|
msgstr "Consulta de búsqueda"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||||
msgid "All"
|
msgid "All"
|
||||||
@@ -1058,7 +1058,7 @@ msgstr "febrero"
|
|||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:80
|
#: pretix/static/pretixpresale/js/widget/widget.js:80
|
||||||
msgid "March"
|
msgid "March"
|
||||||
msgstr "marzo"
|
msgstr "Marzo"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:81
|
#: pretix/static/pretixpresale/js/widget/widget.js:81
|
||||||
msgid "April"
|
msgid "April"
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -7,8 +7,8 @@ msgstr ""
|
|||||||
"Project-Id-Version: French\n"
|
"Project-Id-Version: French\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2024-11-08 13:45+0000\n"
|
"POT-Creation-Date: 2024-11-08 13:45+0000\n"
|
||||||
"PO-Revision-Date: 2024-11-15 11:19+0000\n"
|
"PO-Revision-Date: 2024-11-16 05:00+0000\n"
|
||||||
"Last-Translator: Eva-Maria Obermann <obermann@rami.io>\n"
|
"Last-Translator: CVZ-es <damien.bremont@casadevelazquez.org>\n"
|
||||||
"Language-Team: French <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
"Language-Team: French <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||||
"fr/>\n"
|
"fr/>\n"
|
||||||
"Language: fr\n"
|
"Language: fr\n"
|
||||||
@@ -325,7 +325,7 @@ msgstr "Billets valides"
|
|||||||
|
|
||||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:70
|
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:70
|
||||||
msgid "Currently inside"
|
msgid "Currently inside"
|
||||||
msgstr "Présent actuellement"
|
msgstr "Actuellement à l'intérieur"
|
||||||
|
|
||||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:71
|
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:71
|
||||||
#: pretix/static/pretixcontrol/js/ui/question.js:137
|
#: pretix/static/pretixcontrol/js/ui/question.js:137
|
||||||
@@ -457,7 +457,7 @@ msgstr "Pont"
|
|||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:111
|
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:111
|
||||||
msgid "Current date and time"
|
msgid "Current date and time"
|
||||||
msgstr "Date actuelle"
|
msgstr "Date et heure actuelle"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:115
|
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:115
|
||||||
msgid "Current day of the week (1 = Monday, 7 = Sunday)"
|
msgid "Current day of the week (1 = Monday, 7 = Sunday)"
|
||||||
@@ -465,7 +465,7 @@ msgstr "Jour courant de la semaine (1 = Lundi, 7 = Dimanche)"
|
|||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:119
|
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:119
|
||||||
msgid "Current entry status"
|
msgid "Current entry status"
|
||||||
msgstr ""
|
msgstr "Statut actuel de l'entrée"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:123
|
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:123
|
||||||
msgid "Number of previous entries"
|
msgid "Number of previous entries"
|
||||||
@@ -488,16 +488,12 @@ msgid "Number of days with a previous entry"
|
|||||||
msgstr "Nombre de jours avec entrée préalable"
|
msgstr "Nombre de jours avec entrée préalable"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:143
|
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:143
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Number of days with a previous entry"
|
|
||||||
msgid "Number of days with a previous entry since"
|
msgid "Number of days with a previous entry since"
|
||||||
msgstr "Nombre de jours avec entrée préalable"
|
msgstr "Nombre de jours avec entrée préalable depuis"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:147
|
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:147
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Number of days with a previous entry"
|
|
||||||
msgid "Number of days with a previous entry before"
|
msgid "Number of days with a previous entry before"
|
||||||
msgstr "Nombre de jours avec entrée préalable"
|
msgstr "Nombre de jours avec entrée préalable avant"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:151
|
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:151
|
||||||
msgid "Minutes since last entry (-1 on first entry)"
|
msgid "Minutes since last entry (-1 on first entry)"
|
||||||
@@ -650,7 +646,7 @@ msgstr ""
|
|||||||
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr "Recherche"
|
msgstr "Requête de recherche"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||||
msgid "All"
|
msgid "All"
|
||||||
@@ -708,7 +704,7 @@ msgid ""
|
|||||||
"complete your order as long as they’re available."
|
"complete your order as long as they’re available."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Les articles de votre panier ne vous sont plus réservés. Vous pouvez "
|
"Les articles de votre panier ne vous sont plus réservés. Vous pouvez "
|
||||||
"toujours terminer votre commande tant qu’ils sont disponibles."
|
"toujours compléter votre commande tant qu'ils sont disponibles."
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/cart.js:45
|
#: pretix/static/pretixpresale/js/ui/cart.js:45
|
||||||
msgid "Cart expired"
|
msgid "Cart expired"
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -8,17 +8,17 @@ msgstr ""
|
|||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2024-11-08 13:45+0000\n"
|
"POT-Creation-Date: 2024-11-08 13:45+0000\n"
|
||||||
"PO-Revision-Date: 2024-01-31 04:00+0000\n"
|
"PO-Revision-Date: 2024-11-17 00:00+0000\n"
|
||||||
"Last-Translator: Pavle Ergović <pavleergovic@gmail.com>\n"
|
"Last-Translator: Pavle Ergović <pavleergovic@gmail.com>\n"
|
||||||
"Language-Team: Croatian <https://translate.pretix.eu/projects/pretix/pretix-"
|
"Language-Team: Croatian <https://translate.pretix.eu/projects/pretix/"
|
||||||
"js/hr/>\n"
|
"pretix-js/hr/>\n"
|
||||||
"Language: hr\n"
|
"Language: hr\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
|
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
|
||||||
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
|
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
|
||||||
"X-Generator: Weblate 5.3.1\n"
|
"X-Generator: Weblate 5.8.3\n"
|
||||||
|
|
||||||
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
|
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
|
||||||
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
|
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
|
||||||
@@ -307,7 +307,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:65
|
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:65
|
||||||
msgid "Order canceled"
|
msgid "Order canceled"
|
||||||
msgstr ""
|
msgstr "Narudžba otkazana"
|
||||||
|
|
||||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:66
|
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:66
|
||||||
msgid "Ticket code is ambiguous on list"
|
msgid "Ticket code is ambiguous on list"
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: 1\n"
|
"Project-Id-Version: 1\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2024-11-08 13:45+0000\n"
|
"POT-Creation-Date: 2024-11-18 15:16+0000\n"
|
||||||
"PO-Revision-Date: 2024-10-23 14:30+0000\n"
|
"PO-Revision-Date: 2024-10-23 14:30+0000\n"
|
||||||
"Last-Translator: arjan-s <github@anymore.nl>\n"
|
"Last-Translator: arjan-s <github@anymore.nl>\n"
|
||||||
"Language-Team: Dutch <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
"Language-Team: Dutch <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||||
@@ -645,48 +645,38 @@ msgstr ""
|
|||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:495
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr "Zoekopdracht"
|
msgstr "Zoekopdracht"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:513
|
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Alle"
|
msgstr "Alle"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr "Geen"
|
msgstr "Geen"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:519
|
#: pretix/static/pretixcontrol/js/ui/main.js:519
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:518
|
|
||||||
msgid "Selected only"
|
msgid "Selected only"
|
||||||
msgstr "Alleen geselecteerde"
|
msgstr "Alleen geselecteerde"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:862
|
#: pretix/static/pretixcontrol/js/ui/main.js:862
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:861
|
|
||||||
msgid "Enter page number between 1 and %(max)s."
|
msgid "Enter page number between 1 and %(max)s."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:865
|
#: pretix/static/pretixcontrol/js/ui/main.js:865
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:864
|
|
||||||
msgid "Invalid page number."
|
msgid "Invalid page number."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1023
|
#: pretix/static/pretixcontrol/js/ui/main.js:1023
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1022
|
|
||||||
msgid "Use a different name internally"
|
msgid "Use a different name internally"
|
||||||
msgstr "Gebruik intern een andere naam"
|
msgstr "Gebruik intern een andere naam"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1063
|
#: pretix/static/pretixcontrol/js/ui/main.js:1063
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1062
|
|
||||||
msgid "Click to close"
|
msgid "Click to close"
|
||||||
msgstr "Klik om te sluiten"
|
msgstr "Klik om te sluiten"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1138
|
#: pretix/static/pretixcontrol/js/ui/main.js:1138
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1137
|
|
||||||
msgid "You have unsaved changes!"
|
msgid "You have unsaved changes!"
|
||||||
msgstr "U heeft nog niet opgeslagen wijzigingen!"
|
msgstr "U heeft nog niet opgeslagen wijzigingen!"
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user