Compare commits

..
5 Commits
201 changed files with 26714 additions and 72919 deletions
-51
View File
@@ -1,51 +0,0 @@
name: SBOM
on:
push:
branches: [ master, sbom ]
tags: [ 'v.*' ]
permissions:
contents: read # to fetch code (actions/checkout)
env:
FORCE_COLOR: 1
jobs:
test:
runs-on: ubuntu-22.04
name: Submission
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.13"
- uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-
- name: Install system dependencies
run: sudo apt update && sudo apt install -y gettext unzip jq
- name: Install node dependencies
run: sudo npm install --global @cyclonedx/cyclonedx-npm
- name: Install Python dependencies
run: pip3 install -U uv cyclonedx-bom prisma-sbom-submit
- name: Create empty environment
run: uv venv sbom-env
- name: Install package
run: uv pip install --python ./sbom-env/bin/python .
- name: Create Python SBOM
run: cyclonedx-py environment sbom-env > sbom-python.json
- name: Install node dependencies
run: npm ci
- name: Create JavaScript SBOM
run: cyclonedx-npm > sbom-npm.json
- name: Merge SBOMs
run: jq -s "[.[0], .[1]]" sbom-python.json sbom-npm.json > sbom.json
- name: Submit SBOM
run: prisma-sbom-submit --server https://prisma.pretix.com sbom.json
env:
PRISMA_UPLOAD_TOKEN: ${{ secrets.PRISMA_UPLOAD_TOKEN }}
+1 -2
View File
@@ -351,8 +351,7 @@ Endpoints
:<json boolean error_reason: One of ``canceled``, ``invalid``, ``unpaid``, ``product``, ``rules``, ``revoked``,
``incomplete``, ``already_redeemed``, ``blocked``, ``invalid_time``, or ``error``. Required.
:<json raw_barcode: The raw barcode or identifier you scanned. Required.
:<json raw_source_type: The type of medium you scanned, defaults to ``barcode``. Optional.
:<json raw_barcode: The raw barcode you scanned. Required.
:<json datetime: Date and time of the scan. Optional.
:<json type: Type of scan, defaults to ``"entry"``.
:<json position: Internal ID of an order position you matched. Optional.
-6
View File
@@ -864,9 +864,6 @@ Generating new secrets
Triggers generation of new ``secret`` and ``web_secret`` attributes for both the order and all order positions.
Ticket secrets of order positions that have been used to issue a gift card can not
be changed. Only the link (``web_secret``) will be changed in this case.
**Example request**:
.. sourcecode:: http
@@ -898,9 +895,6 @@ Generating new secrets
Triggers generation of a new ``secret`` and ``web_secret`` attribute for a single order position.
Ticket secrets of order positions that have been used to issue a gift card can not
be changed. Only the link (``web_secret``) will be changed in this case.
**Example request**:
.. sourcecode:: http
+10 -10
View File
@@ -2584,9 +2584,9 @@
}
},
"node_modules/immutable": {
"version": "5.1.9",
"resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.9.tgz",
"integrity": "sha512-m8nVez3rwrgmWxtLMt1ZYXB2Lv7OKYn/disyxAlSDYAlKSlFoPPfIAmAM/M5xqL4m4C/wAPw7S2/CNaUii1Hxg==",
"version": "5.1.5",
"resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.5.tgz",
"integrity": "sha512-t7xcm2siw+hlUM68I+UEOK+z84RzmN59as9DZ7P1l0994DKUWV7UXBMQZVxaoMSRQ+PBZbHCOoBt7a2wxOMt+A==",
"dev": true,
"license": "MIT"
},
@@ -3176,9 +3176,9 @@
"license": "MIT"
},
"node_modules/nanoid": {
"version": "3.3.16",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz",
"integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==",
"version": "3.3.12",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz",
"integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==",
"funding": [
{
"type": "github",
@@ -3352,9 +3352,9 @@
}
},
"node_modules/postcss": {
"version": "8.5.23",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.23.tgz",
"integrity": "sha512-g50586zr4bZmwFiTlflMu8E0bDTb5I5gertgwAKmsdUlTQIhZtunzUlD1WSzwcVWPoAVpsrA6vlfCD7oXvRwgg==",
"version": "8.5.15",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz",
"integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==",
"funding": [
{
"type": "opencollective",
@@ -3371,7 +3371,7 @@
],
"license": "MIT",
"dependencies": {
"nanoid": "^3.3.16",
"nanoid": "^3.3.12",
"picocolors": "^1.1.1",
"source-map-js": "^1.2.1"
},
+8 -8
View File
@@ -40,11 +40,11 @@ dependencies = [
"Django[argon2]==5.2.*",
"django-bootstrap3==26.1",
"django-compressor==4.6.0",
"django-countries==9.0.*",
"django-filter==26.1",
"django-countries==8.2.*",
"django-filter==25.1",
"django-formset-js-improved==0.5.0.5",
"django-formtools==2.7",
"django-hierarkey==2.0.*,>=2.0.2",
"django-hierarkey==2.0.*,>=2.0.1",
"django-hijack==3.7.*",
"django-i18nfield==1.11.*",
"django-libsass==0.9",
@@ -52,10 +52,10 @@ dependencies = [
"django-markup",
"django-oauth-toolkit==2.3.*",
"django-otp==1.7.*",
"django-phonenumber-field==8.5.*",
"django-phonenumber-field==8.4.*",
"django-querytagger==0.0.3",
"django-redis==7.0.*",
"django-scopes==2.1.*",
"django-scopes==2.0.*",
"django-statici18n==2.7.*",
"djangorestframework==3.17.*",
"dnspython==2.8.*",
@@ -94,11 +94,11 @@ dependencies = [
"redis==7.4.*",
"reportlab==5.0.*",
"requests==2.34.*",
"sentry-sdk==2.66.*",
"sentry-sdk==2.64.*",
"sepaxml==2.7.*",
"stripe==7.9.*",
"text-unidecode==1.*",
"tlds>=2026072401",
"tlds>=2026041800",
"tqdm==4.*",
"ua-parser==1.0.*",
"vobject==0.9.*",
@@ -112,7 +112,7 @@ dev = [
"aiohttp==3.14.*",
"coverage",
"coveralls",
"fakeredis==2.37.*",
"fakeredis==2.36.*",
"flake8==7.3.*",
"freezegun",
"isort==8.0.*",
+1 -1
View File
@@ -19,4 +19,4 @@
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
# <https://www.gnu.org/licenses/>.
#
__version__ = "2026.8.0.dev0"
__version__ = "2026.7.0.dev0"
+4 -16
View File
@@ -20,6 +20,7 @@
# <https://www.gnu.org/licenses/>.
#
import logging
from collections import OrderedDict
from django.dispatch import receiver
from django.utils.translation import gettext_lazy as _
@@ -51,18 +52,10 @@ class BaseSecurityProfile:
"""
raise NotImplementedError()
@property
def priority(self) -> int:
"""
Priority for ordering, higher will come first.
"""
return 100
class FullAccessSecurityProfile(BaseSecurityProfile):
identifier = 'full'
verbose_name = _('Full device access (reading and changing orders and gift cards, reading of products and settings)')
priority = 1000
def is_allowed(self, request):
return True
@@ -115,7 +108,6 @@ class PretixScanSecurityProfile(AllowListSecurityProfile):
('GET', 'api-v1:event.settings'),
('POST', 'api-v1:upload'),
('POST', 'api-v1:checkinrpc.redeem'),
('POST', 'api-v1:checkinrpc.annull'),
('GET', 'api-v1:checkinrpc.search'),
('GET', 'api-v1:reusablemedium-list'),
('POST', 'api-v1:reusablemedium-lookup'),
@@ -154,7 +146,6 @@ class PretixScanNoSyncNoSearchSecurityProfile(AllowListSecurityProfile):
('GET', 'api-v1:event.settings'),
('POST', 'api-v1:upload'),
('POST', 'api-v1:checkinrpc.redeem'),
('POST', 'api-v1:checkinrpc.annull'),
('GET', 'api-v1:checkinrpc.search'),
)
@@ -191,7 +182,6 @@ class PretixScanNoSyncSecurityProfile(AllowListSecurityProfile):
('GET', 'api-v1:event.settings'),
('POST', 'api-v1:upload'),
('POST', 'api-v1:checkinrpc.redeem'),
('POST', 'api-v1:checkinrpc.annull'),
('GET', 'api-v1:checkinrpc.search'),
)
@@ -202,15 +192,13 @@ def get_all_security_profiles():
if _ALL_PROFILES:
return _ALL_PROFILES
types = []
types = OrderedDict()
for recv, ret in register_device_security_profile.send(None):
if isinstance(ret, (list, tuple)):
for r in ret:
types.append(r)
types[r.identifier] = r
else:
types.append(ret)
types.sort(key=lambda el: el.priority, reverse=True)
types = {r.identifier: r for r in types}
types[ret.identifier] = ret
_ALL_PROFILES = types
return types
-28
View File
@@ -20,7 +20,6 @@
# <https://www.gnu.org/licenses/>.
#
import json
import re
from django.db.models import prefetch_related_objects
from rest_framework import serializers
@@ -136,30 +135,3 @@ class SalesChannelMigrationMixin:
else:
value["sales_channels"] = value["limit_sales_channels"]
return value
class CompatDecimalField(serializers.DecimalField):
"""
Historically, pretix recorded tax rates as decimals with two places. Today, pretix supports tax rates with up to
four places. Since our API outputs decimals with the stored precision, this would have changed the API output from
"19.00" to "19.0000" without warning. While this is semantically the same thing, we need to assume some pretix API
users might run into trouble, either because they treat the value as a string and then map something
(e.g. ``if tax_rate == "19.00"``) or process it with a language where this is a significant difference. For example,
while in Python ``Decimal("19.00") == Decimal("19.0000")`` is true, in Java
``(new BigDecimal("19.00")).equals(new BigDecimal("19.0000"))`` is false and only
``(new BigDecimal("19.00")).compareTo(new BigDecimal("19.0000")) == 0`` is true.
Therefore, we stay backwards compatible by outputting two decimal places *as long as the trailing digits are zero-valued.
"""
regex = re.compile(r"^([0-9]+\.[0-9]{2})0+$")
def to_representation(self, value):
if self.localize:
raise ValueError("localization not supported")
value = super().to_representation(value)
if value and "." not in value:
return f"{value}.00"
if m := self.regex.match(value):
return m.group(1)
return value
+1 -2
View File
@@ -48,7 +48,7 @@ from rest_framework.fields import ChoiceField, Field
from rest_framework.relations import SlugRelatedField
from pretix.api.serializers import (
CompatDecimalField, CompatibleJSONField, SalesChannelMigrationMixin,
CompatibleJSONField, SalesChannelMigrationMixin,
)
from pretix.api.serializers.fields import PluginsField
from pretix.api.serializers.i18n import I18nAwareModelSerializer
@@ -681,7 +681,6 @@ class TaxRuleSerializer(CountryFieldMixin, I18nAwareModelSerializer):
required=False,
allow_null=True,
)
rate = CompatDecimalField(max_digits=7, decimal_places=4)
class Meta:
model = TaxRule
+4 -6
View File
@@ -42,9 +42,7 @@ from django.utils.functional import cached_property, lazy
from django.utils.translation import gettext_lazy as _
from rest_framework import serializers
from pretix.api.serializers import (
CompatDecimalField, SalesChannelMigrationMixin,
)
from pretix.api.serializers import SalesChannelMigrationMixin
from pretix.api.serializers.event import MetaDataField
from pretix.api.serializers.fields import UploadedFileField
from pretix.api.serializers.i18n import I18nAwareModelSerializer
@@ -278,10 +276,10 @@ class ItemAddOnSerializer(serializers.ModelSerializer):
return value
class ItemTaxRateField(CompatDecimalField):
class ItemTaxRateField(serializers.Field):
def to_representation(self, i):
if i.tax_rule:
return super().to_representation(Decimal(i.tax_rule.rate))
return str(Decimal(i.tax_rule.rate))
else:
return str(Decimal('0.00'))
@@ -291,7 +289,7 @@ class ItemSerializer(SalesChannelMigrationMixin, I18nAwareModelSerializer):
bundles = InlineItemBundleSerializer(many=True, required=False)
variations = InlineItemVariationSerializer(many=True, required=False)
program_times = InlineItemProgramTimeSerializer(many=True, required=False)
tax_rate = ItemTaxRateField(source='*', read_only=True, max_digits=7, decimal_places=4)
tax_rate = ItemTaxRateField(source='*', read_only=True)
meta_data = MetaDataField(required=False, source='*')
picture = UploadedFileField(required=False, allow_null=True, allowed_types=(
'image/png', 'image/jpeg', 'image/gif'
+2 -9
View File
@@ -41,7 +41,7 @@ from rest_framework.exceptions import ValidationError
from rest_framework.relations import SlugRelatedField
from rest_framework.reverse import reverse
from pretix.api.serializers import CompatDecimalField, CompatibleJSONField
from pretix.api.serializers import CompatibleJSONField
from pretix.api.serializers.event import SubEventSerializer
from pretix.api.serializers.forms import form_field_to_serializer_field
from pretix.api.serializers.i18n import I18nAwareModelSerializer
@@ -52,7 +52,6 @@ from pretix.api.signals import order_api_details, orderposition_api_details
from pretix.base.decimal import round_decimal
from pretix.base.i18n import language
from pretix.base.invoicing.transmission import get_transmission_types
from pretix.base.media import MEDIA_TYPES
from pretix.base.models import (
CachedFile, Checkin, Customer, Device, GiftCard, Invoice, InvoiceAddress,
InvoiceLine, Item, ItemVariation, Order, OrderPosition, Question,
@@ -382,7 +381,6 @@ class PrintLogSerializer(serializers.ModelSerializer):
class FailedCheckinSerializer(I18nAwareModelSerializer):
error_reason = serializers.ChoiceField(choices=Checkin.REASONS, required=True, allow_null=False)
raw_barcode = serializers.CharField(required=True, allow_null=False)
raw_source_type = serializers.ChoiceField(choices=[(k, v) for k, v in MEDIA_TYPES.items()], default='barcode')
position = serializers.PrimaryKeyRelatedField(queryset=OrderPosition.all.none(), required=False, allow_null=True)
raw_item = serializers.PrimaryKeyRelatedField(queryset=Item.objects.none(), required=False, allow_null=True)
raw_variation = serializers.PrimaryKeyRelatedField(queryset=ItemVariation.objects.none(), required=False, allow_null=True)
@@ -392,7 +390,7 @@ class FailedCheckinSerializer(I18nAwareModelSerializer):
class Meta:
model = Checkin
fields = ('error_reason', 'error_explanation', 'raw_barcode', 'raw_item', 'raw_variation',
'raw_subevent', 'raw_source_type', 'nonce', 'datetime', 'type', 'position')
'raw_subevent', 'nonce', 'datetime', 'type', 'position')
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
@@ -593,7 +591,6 @@ class OrderPositionSerializer(I18nAwareModelSerializer):
country = CompatibleCountryField(source='*')
attendee_name = serializers.CharField(required=False)
plugin_data = OrderPositionPluginDataField(source='*', allow_null=True, read_only=True)
tax_rate = CompatDecimalField(max_digits=7, decimal_places=4)
class Meta:
list_serializer_class = OrderPositionListSerializer
@@ -750,8 +747,6 @@ class OrderPaymentDateField(serializers.DateField):
class OrderFeeSerializer(I18nAwareModelSerializer):
tax_rate = CompatDecimalField(max_digits=7, decimal_places=4)
class Meta:
model = OrderFee
fields = ('id', 'fee_type', 'value', 'description', 'internal_type', 'tax_rate', 'tax_value', 'tax_rule',
@@ -1916,7 +1911,6 @@ class InlineInvoiceLineSerializer(I18nAwareModelSerializer):
position = LinePositionField(read_only=True)
event_date_from = serializers.DateTimeField(read_only=True, source="period_start")
event_date_to = serializers.DateTimeField(read_only=True, source="period_end")
tax_rate = CompatDecimalField(max_digits=7, decimal_places=4)
class Meta:
model = InvoiceLine
@@ -2000,7 +1994,6 @@ class BlockedTicketSecretSerializer(I18nAwareModelSerializer):
class TransactionSerializer(I18nAwareModelSerializer):
order = serializers.SlugRelatedField(slug_field="code", read_only=True)
tax_rate = CompatDecimalField(max_digits=7, decimal_places=4)
class Meta:
model = Transaction
+1 -2
View File
@@ -45,7 +45,6 @@ from rest_framework.exceptions import (
NotFound, PermissionDenied, ValidationError,
)
from rest_framework.generics import get_object_or_404
from rest_framework.mixins import UpdateModelMixin
from rest_framework.response import Response
from pretix.api.auth.permission import EventCRUDPermission
@@ -712,7 +711,7 @@ class SeatFilter(FilterSet):
fields = ('zone_name', 'row_name', 'row_label', 'seat_number', 'seat_label', 'seat_guid', 'blocked',)
class SeatViewSet(ConditionalListView, UpdateModelMixin, viewsets.ReadOnlyModelViewSet):
class SeatViewSet(ConditionalListView, viewsets.ModelViewSet):
serializer_class = SeatSerializer
queryset = Seat.objects.none()
write_permission = 'event.settings.general:write'
+1 -3
View File
@@ -1658,7 +1658,6 @@ class PaymentViewSet(CreateModelMixin, viewsets.ReadOnlyModelViewSet):
count_waitinglist=False,
force=request.data.get('force', False),
send_mail=send_mail,
ignore_date=request.data.get('force', False),
)
except Quota.QuotaExceededException:
pass
@@ -1694,8 +1693,7 @@ class PaymentViewSet(CreateModelMixin, viewsets.ReadOnlyModelViewSet):
auth=self.request.auth,
count_waitinglist=False,
send_mail=send_mail,
force=force,
ignore_date=force)
force=force)
except Quota.QuotaExceededException as e:
return Response({'detail': str(e)}, status=status.HTTP_400_BAD_REQUEST)
except PaymentException as e:
+9 -12
View File
@@ -23,7 +23,6 @@ import sys
from django.conf import settings
from django.urls import reverse
from django.utils.html import escape, format_html
from django.utils.safestring import mark_safe
from django.utils.translation import gettext
@@ -36,23 +35,21 @@ def get_powered_by(request, safelink=True):
d = gs.settings.license_check_input
if d.get('poweredby_name'):
if d.get('poweredby_url'):
msg = format_html(
gettext('<a {a_name_attr}>powered by {name}</a> <a {a_attr}>based on pretix</a>'),
msg = gettext('<a {a_name_attr}>powered by {name}</a> <a {a_attr}>based on pretix</a>').format(
name=d['poweredby_name'],
a_name_attr=mark_safe('href="{}" target="_blank" rel="noopener"'.format(
escape(sl(d['poweredby_url'])) if safelink else escape(d['poweredby_url']),
)),
a_attr=mark_safe('href="{}" target="_blank" rel="noopener"'.format(
a_name_attr='href="{}" target="_blank" rel="noopener"'.format(
sl(d['poweredby_url']) if safelink else d['poweredby_url'],
),
a_attr='href="{}" target="_blank" rel="noopener"'.format(
sl('https://pretix.eu') if safelink else 'https://pretix.eu',
))
)
)
else:
msg = format_html(
gettext('<a {a_attr}>powered by {name} based on pretix</a>'),
msg = gettext('<a {a_attr}>powered by {name} based on pretix</a>').format(
name=d['poweredby_name'],
a_attr=mark_safe('href="{}" target="_blank" rel="noopener"'.format(
a_attr='href="{}" target="_blank" rel="noopener"'.format(
sl('https://pretix.eu') if safelink else 'https://pretix.eu',
))
)
)
else:
msg = gettext('<a %(a_attr)s>ticketing powered by pretix</a>') % {
+13 -4
View File
@@ -19,6 +19,7 @@
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
# <https://www.gnu.org/licenses/>.
#
import ipaddress
import logging
import smtplib
import socket
@@ -42,7 +43,6 @@ from pretix.base.templatetags.rich_text import (
markdown_compile_email, truelink_callback,
)
from pretix.helpers.format import FormattedString, SafeFormatter, format_map
from pretix.helpers.ssrf import should_block_access
from pretix.base.services.placeholders import ( # noqa
get_available_placeholders, PlaceholderContext
@@ -57,6 +57,8 @@ logger = logging.getLogger('pretix.base.email')
T = TypeVar("T", bound=EmailBackend)
_cgnat_net = ipaddress.ip_network('100.64.0.0/10')
def test_custom_smtp_backend(backend: T, from_addr: str) -> None:
try:
@@ -252,9 +254,16 @@ def create_connection(address, timeout=socket.getdefaulttimeout(),
af, socktype, proto, canonname, sa = res
if not getattr(settings, "MAIL_CUSTOM_SMTP_ALLOW_PRIVATE_NETWORKS", False):
is_private, msg = should_block_access(sa)
if is_private:
raise socket.error(msg)
ip_addr = ipaddress.ip_address(sa[0])
check_ip4 = ip_addr.ipv4_mapped if getattr(ip_addr, "ipv4_mapped", None) else ip_addr
if ip_addr.is_multicast:
raise socket.error(f"Request to multicast address {sa[0]} blocked")
if ip_addr.is_loopback or ip_addr.is_link_local:
raise socket.error(f"Request to local address {sa[0]} blocked")
if ip_addr.is_private:
raise socket.error(f"Request to private address {sa[0]} blocked")
if check_ip4 in _cgnat_net:
raise socket.error(f"Request to RFC 6598 address {sa[0]} blocked")
sock = None
try:
+3 -57
View File
@@ -40,12 +40,11 @@ from django.utils.translation import gettext as _, gettext_lazy, pgettext_lazy
from pretix.base.settings import PERSON_NAME_SCHEMES
from ..exporter import MultiSheetListExporter, OrganizerLevelExportMixin
from ..models import Membership
from ..exporter import ListExporter, OrganizerLevelExportMixin
from ..signals import register_multievent_data_exporters
class CustomerListExporter(OrganizerLevelExportMixin, MultiSheetListExporter):
class CustomerListExporter(OrganizerLevelExportMixin, ListExporter):
identifier = 'customerlist'
verbose_name = gettext_lazy('Customer accounts')
category = pgettext_lazy('export_category', 'Customer accounts')
@@ -55,20 +54,13 @@ class CustomerListExporter(OrganizerLevelExportMixin, MultiSheetListExporter):
def get_required_organizer_permission(cls) -> str:
return 'organizer.customers:write'
@property
def sheets(self):
return (
('customers', _('Customers')),
('memberships', _('Memberships')),
)
@property
def additional_form_fields(self):
return OrderedDict(
[]
)
def iterate_customers(self, form_data):
def iterate_list(self, form_data):
qs = self.organizer.customers.prefetch_related('provider')
headers = [
@@ -117,52 +109,6 @@ class CustomerListExporter(OrganizerLevelExportMixin, MultiSheetListExporter):
]
yield row
def iterate_memberships(self, form_data):
qs = Membership.objects.filter(
customer__organizer=self.organizer
).prefetch_related('membership_type').select_related('customer', 'granted_in', 'granted_in__order')
headers = [
_('Customer ID'),
_('External identifier'),
_('Email'),
_('Test mode'),
_('Canceled'),
_('Membership type'),
_('Purchase ticket'),
_('Start date'),
_('Start time'),
_('End date'),
_('End time'),
_('Name'),
]
name_scheme = PERSON_NAME_SCHEMES[self.organizer.settings.name_scheme]
if name_scheme and len(name_scheme['fields']) > 1:
for k, label, w in name_scheme['fields']:
headers.append(_('Name') + ': ' + str(label))
yield headers
tz = get_current_timezone()
for obj in qs:
row = [
obj.customer.identifier,
obj.customer.external_identifier,
obj.customer.email or '',
_('Yes') if obj.testmode else _('No'),
_('Yes') if obj.canceled else _('No'),
str(obj.membership_type.name),
f'{obj.granted_in.order.code}-{obj.granted_in.positionid}' if obj.granted_in else None,
obj.date_start.astimezone(tz).strftime('%Y-%m-%d'),
obj.date_start.astimezone(tz).strftime('%H:%M'),
obj.date_end.astimezone(tz).strftime('%Y-%m-%d'),
obj.date_end.astimezone(tz).strftime('%H:%M'),
obj.attendee_name or '',
]
if name_scheme and len(name_scheme['fields']) > 1:
for k, label, w in name_scheme['fields']:
row.append(obj.attendee_name_parts.get(k, ''))
yield row
def get_filename(self):
return '{}_customers'.format(self.organizer.slug)
+32 -9
View File
@@ -33,6 +33,8 @@
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under the License.
import hashlib
import ipaddress
import logging
from django import forms
@@ -40,12 +42,13 @@ from django.conf import settings
from django.contrib.auth.password_validation import (
password_validators_help_texts, validate_password,
)
from django.utils.functional import cached_property
from django.utils.translation import gettext_lazy as _
from pretix.base.metrics import pretix_failed_logins
from pretix.base.models import User
from pretix.helpers.dicts import move_to_end
from pretix.helpers.ratelimit import rate_limit
from pretix.helpers.http import get_client_ip
logger = logging.getLogger(__name__)
@@ -82,20 +85,40 @@ class LoginForm(forms.Form):
else:
move_to_end(self.fields, 'keep_logged_in')
@cached_property
def ratelimit_key(self):
if not settings.HAS_REDIS:
return None
client_ip = get_client_ip(self.request)
if not client_ip:
return None
try:
client_ip = ipaddress.ip_address(client_ip)
except ValueError:
# Web server not set up correctly
return None
if client_ip.is_private:
# This is the private IP of the server, web server not set up correctly
return None
return 'pretix_login_{}'.format(hashlib.sha1(str(client_ip).encode()).hexdigest())
def clean(self):
if all(k in self.cleaned_data for k, f in self.fields.items() if f.required):
rate_limit_kwargs = dict(include_ip_from_request=self.request, max_num=10, expire_time=300)
if rate_limit("login", **rate_limit_kwargs, increase=False):
# Check rate limit without counting up, we increase below only on failed logins
pretix_failed_logins.inc(1, reason="ratelimit")
logger.info("Backend login rejected due to rate limit.")
raise forms.ValidationError(self.error_messages['rate_limit'], code='rate_limit')
if self.ratelimit_key:
from django_redis import get_redis_connection
rc = get_redis_connection("redis")
cnt = rc.get(self.ratelimit_key)
if cnt and int(cnt) > 10:
pretix_failed_logins.inc(1, reason="ratelimit")
logger.info("Backend login rejected due to rate limit.")
raise forms.ValidationError(self.error_messages['rate_limit'], code='rate_limit')
self.user_cache = self.backend.form_authenticate(self.request, self.cleaned_data)
if self.user_cache is None:
if self.ratelimit_key:
rc.incr(self.ratelimit_key)
rc.expire(self.ratelimit_key, 300)
logger.info("Backend login invalid.")
pretix_failed_logins.inc(1, reason="invalid")
# Count towards rate limit (result is ignored, we are checking above)
rate_limit("login", **rate_limit_kwargs)
raise forms.ValidationError(
self.error_messages['invalid_login'],
code='invalid_login'
+1 -8
View File
@@ -959,7 +959,7 @@ class BaseQuestionsForm(forms.Form):
label=label, required=required,
help_text=help_text,
initial=_initial,
widget=TimePickerWidget(without_seconds=True),
widget=TimePickerWidget(time_format=get_format_without_seconds('TIME_INPUT_FORMATS')),
)
elif q.type == Question.TYPE_DATETIME:
if not help_text:
@@ -1116,13 +1116,6 @@ class BaseQuestionsForm(forms.Form):
if q.dependency_question_id and not question_is_visible(q.dependency_question_id, q.dependency_values) and answer is not None:
d['question_%d' % q.pk] = None
# Strip False answers to required yes/no questions even if all_optional is set, as our data model assumes that
# required yes/no questions can only be answered with yes
for q in question_cache.values():
if q.required and q.type == Question.TYPE_BOOLEAN:
if 'question_%d' % q.pk in d and d['question_%d' % q.pk] is False:
d['question_%d' % q.pk] = None
return d
+11 -22
View File
@@ -33,6 +33,7 @@
# License for the specific language governing permissions and limitations under the License.
from django import forms
from django.conf import settings
from django.contrib.auth.hashers import check_password
from django.contrib.auth.password_validation import (
password_validators_help_texts, validate_password,
@@ -45,7 +46,6 @@ from pytz import common_timezones
from pretix.base.models import User
from pretix.control.forms import SingleLanguageWidget
from pretix.helpers.format import format_map
from pretix.helpers.ratelimit import rate_limit
class UserSettingsForm(forms.ModelForm):
@@ -128,11 +128,16 @@ class UserPasswordChangeForm(forms.Form):
def clean_old_pw(self):
old_pw = self.cleaned_data.get('old_pw')
if rate_limit("pwchange", self.user.pk, max_num=10, expire_time=300):
raise forms.ValidationError(
self.error_messages['rate_limit'],
code='rate_limit',
)
if settings.HAS_REDIS:
from django_redis import get_redis_connection
rc = get_redis_connection("redis")
cnt = rc.incr('pretix_pwchange_%s' % self.user.pk)
rc.expire('pretix_pwchange_%s' % self.user.pk, 300)
if cnt > 10:
raise forms.ValidationError(
self.error_messages['rate_limit'],
code='rate_limit',
)
if not check_password(old_pw, self.user.password):
raise forms.ValidationError(
@@ -170,35 +175,19 @@ class UserEmailChangeForm(forms.Form):
error_messages = {
'duplicate_identifier': _("There already is an account associated with this email address. "
"Please choose a different one."),
'rate_limit': _("For security reasons, please wait 5 minutes before you try again."),
}
old_email = forms.EmailField(label=_('Old email address'), disabled=True)
new_email = forms.EmailField(label=_('New email address'))
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user')
self.request = kwargs.pop('request')
super().__init__(*args, **kwargs)
def clean_new_email(self):
email = self.cleaned_data['new_email']
if rate_limit("emailchange_attempt", include_ip_from_request=self.request, max_num=5, expire_time=300):
# Rate limit lookup for conflicting email addresses to make enumeration harder
raise forms.ValidationError(
self.error_messages['rate_limit'],
code='rate_limit',
)
if User.objects.filter(Q(email__iexact=email) & ~Q(pk=self.user.pk)).exists():
raise forms.ValidationError(
self.error_messages['duplicate_identifier'],
code='duplicate_identifier',
)
if rate_limit("emailchange", self.user.pk, max_num=2, expire_time=300):
raise forms.ValidationError(
self.error_messages['rate_limit'],
code='rate_limit',
)
return email
+5 -50
View File
@@ -43,10 +43,6 @@ from django.utils.timezone import get_current_timezone, now
from django.utils.translation import gettext_lazy as _
from pretix.helpers.format import PlainHtmlAlternativeString
from pretix.helpers.i18n import (
get_format_without_seconds, get_javascript_format,
get_javascript_format_without_seconds,
)
def replace_arabic_numbers(inp):
@@ -112,7 +108,7 @@ class DatePickerWidget(forms.DateInput):
class TimePickerWidget(forms.TimeInput):
def __init__(self, attrs=None, time_format=None, without_seconds=False):
def __init__(self, attrs=None, time_format=None):
attrs = attrs or {}
if 'placeholder' in attrs:
del attrs['placeholder']
@@ -121,27 +117,8 @@ class TimePickerWidget(forms.TimeInput):
time_attrs['class'] += ' timepickerfield'
time_attrs['autocomplete'] = 'off'
if time_format or without_seconds:
# Explicitly set data-format attributes for the JS layer instead of relying on the body-wide config
def time_format_attr():
if without_seconds:
return get_javascript_format_without_seconds(time_format or "TIME_INPUT_FORMATS")
return get_javascript_format(time_format or "TIME_INPUT_FORMATS")
time_attrs['data-format'] = lazy(time_format_attr, str)
def time_format_attr():
if without_seconds:
return get_javascript_format_without_seconds(time_format or "TIME_INPUT_FORMATS")
return get_javascript_format(time_format or "TIME_INPUT_FORMATS")
time_attrs['data-format'] = lazy(time_format_attr, str)
def placeholder():
if without_seconds:
tf = time_format or get_format_without_seconds('TIME_INPUT_FORMATS')
else:
tf = time_format or get_format('TIME_INPUT_FORMATS')[0]
tf = time_format or get_format('TIME_INPUT_FORMATS')[0]
return now().replace(
year=2000, month=1, day=1, hour=0, minute=0, second=0, microsecond=0
).strftime(tf)
@@ -205,7 +182,7 @@ class UploadedFileWidget(forms.ClearableFileInput):
class SplitDateTimePickerWidget(forms.SplitDateTimeWidget):
template_name = 'pretixbase/forms/widgets/splitdatetime.html'
def __init__(self, attrs=None, date_format=None, time_format=None, min_date=None, max_date=None, without_seconds=False):
def __init__(self, attrs=None, date_format=None, time_format=None, min_date=None, max_date=None):
attrs = attrs or {}
if 'placeholder' in attrs:
del attrs['placeholder']
@@ -228,36 +205,14 @@ class SplitDateTimePickerWidget(forms.SplitDateTimeWidget):
max_date if not isinstance(max_date, datetime) else max_date.astimezone(get_current_timezone()).date()
).isoformat()
if date_format or time_format or without_seconds:
# Explicitly set data-format attributes for the JS layer instead of relying on the body-wide config
def date_format_attr():
if without_seconds:
return get_javascript_format_without_seconds(date_format or "DATE_INPUT_FORMATS")
return get_javascript_format(date_format or "DATE_INPUT_FORMATS")
date_attrs['data-format'] = lazy(date_format_attr, str)
def time_format_attr():
if without_seconds:
return get_javascript_format_without_seconds(time_format or "TIME_INPUT_FORMATS")
return get_javascript_format(time_format or "TIME_INPUT_FORMATS")
time_attrs['data-format'] = lazy(time_format_attr, str)
def date_placeholder():
if without_seconds:
df = date_format or get_format_without_seconds('DATE_INPUT_FORMATS')
else:
df = date_format or get_format('DATE_INPUT_FORMATS')[0]
df = date_format or get_format('DATE_INPUT_FORMATS')[0]
return now().replace(
year=2000, month=12, day=31, hour=18, minute=0, second=0, microsecond=0
).strftime(df)
def time_placeholder():
if without_seconds:
tf = time_format or get_format_without_seconds('TIME_INPUT_FORMATS')
else:
tf = time_format or get_format('TIME_INPUT_FORMATS')[0]
tf = time_format or get_format('TIME_INPUT_FORMATS')[0]
return now().replace(
year=2000, month=1, day=1, hour=0, minute=0, second=0, microsecond=0
).strftime(tf)
+21 -105
View File
@@ -19,8 +19,6 @@
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
# <https://www.gnu.org/licenses/>.
#
import base64
import hashlib
import logging
import re
from collections import OrderedDict
@@ -71,44 +69,11 @@ def get_supported_language(requested_language, allowed_languages, default_langua
return language
class BaseLocaleMiddleware(MiddlewareMixin):
"""
This is a reduced LocaleMiddleware that uses only information contained in the WSGI request data
to figure out the language (cookie and browser settings). We need it to have a consistent language
for error pages that are generated from the middleware stack before we know e.g. which user is logged
in or which event is selected.
"""
def process_request(self, request: HttpRequest):
language = get_language_from_early_request(request)
translation.activate(language)
set_region(None)
request.LANGUAGE_CODE = language
timezone.deactivate()
def process_response(self, request: HttpRequest, response: HttpResponse):
language = translation.get_language()
patch_vary_headers(response, ('Accept-Language',))
if 'Content-Language' not in response:
response['Content-Language'] = language
return response
class LocaleMiddleware(MiddlewareMixin):
"""
This is the full LocaleMiddleware that uses all available information to figure out the correct
language for the request using all available sources, in this order of priority:
- Backend: User settings
- Language cookie
- Frontend: Customer account settings
- Browser settings
- Frontend: Event/Organizer settings
- System default
It needs to run late in the middleware stack to have all information available for these steps.
For some cases, it is even ran a second time since the event is sometimes only figured out after the
middleware stack (can happen for plugin views).
This middleware sets the correct locale and timezone
for a request.
"""
def process_request(self, request: HttpRequest):
@@ -223,24 +188,6 @@ def get_default_language():
return settings.LANGUAGE_CODE
def get_language_from_early_request(request: HttpRequest) -> str:
"""
Analyzes the request to find what language the user wants the system to
show using only WSGI-available information. Only languages listed in
settings.LANGUAGES are taken into account. If the user requests a sublanguage
where we have a main language, we send out the main language.
"""
global _supported
if _supported is None:
_supported = OrderedDict(settings.LANGUAGES)
return (
get_language_from_cookie(request)
or get_language_from_browser(request)
or get_default_language()
)
def get_language_from_request(request: HttpRequest) -> str:
"""
Analyzes the request to find what language the user wants the system to
@@ -255,6 +202,7 @@ def get_language_from_request(request: HttpRequest) -> str:
if request.path.startswith(get_script_prefix() + 'control'):
return (
get_language_from_user_settings(request)
or get_language_from_customer_settings(request)
or get_language_from_cookie(request)
or get_language_from_browser(request)
or get_language_from_event(request)
@@ -314,28 +262,7 @@ def _merge_csp(a, b):
for k, v in a.items():
if "'unsafe-inline'" in v:
# If we need unsafe-inline, drop any hashes or nonce as they will be ignored otherwise
a[k] = [i for i in v if not i.startswith("'nonce-") and not i.startswith("'sha256-")]
def add_to_response_csp(response, csp_to_merge):
if "Content-Security-Policy" in response:
csp = _parse_csp(response["Content-Security-Policy"])
else:
csp = {}
_merge_csp(csp, csp_to_merge)
if csp:
response["Content-Security-Policy"] = _render_csp(csp)
def add_to_response_csp_via_request(request, csp_to_merge):
_merge_csp(request._csp_to_merge, csp_to_merge)
def calculate_csp_hash(data):
hash_str = base64.b64encode(hashlib.sha256(data.encode("utf-8")).digest()).decode("ascii")
return f"'sha256-{hash_str}'"
a[k] = [i for i in v if not i.startswith("'nonce-") and not i.startswith("'sha-")]
class SecurityMiddleware(MiddlewareMixin):
@@ -355,9 +282,6 @@ class SecurityMiddleware(MiddlewareMixin):
# but at the moment it does not seem to be an issue to just send it.
)
def process_request(self, request):
request._csp_to_merge = {}
def process_response(self, request, resp):
if settings.DEBUG and resp.status_code >= 400:
# Don't use CSP on debug error page as it breaks of Django's fancy error
@@ -369,22 +293,18 @@ class SecurityMiddleware(MiddlewareMixin):
# https://github.com/pretix/pretix/issues/765
resp['P3P'] = 'CP=\"ALL DSP COR CUR ADM TAI OUR IND COM NAV INT\"'
if self._needs_csp(request, resp):
if "Content-Type" in resp and resp["Content-Type"].split(";")[0] in self.SAFE_TYPES:
if 'Content-Security-Policy' in resp:
del resp['Content-Security-Policy']
return resp
if not getattr(resp, '_csp_ignore', False):
resp['Content-Security-Policy'] = _render_csp(self._build_csp(request, resp))
elif 'Content-Security-Policy' in resp:
del resp['Content-Security-Policy']
return resp
def _needs_csp(self, request, resp):
if "Content-Type" in resp and resp["Content-Type"].split(";")[0] in self.SAFE_TYPES:
return False
if getattr(resp, '_csp_ignore', False):
return False
return True
def _build_csp(self, request, resp):
url = resolve(request.path_info)
@@ -394,7 +314,7 @@ class SecurityMiddleware(MiddlewareMixin):
'object-src': ["'none'"],
'frame-src': ['{static}'],
'style-src': ["{static}", "{media}"],
'connect-src': ["{static}", "{dynamic}", "{media}"],
'connect-src': ["{dynamic}", "{media}"],
'img-src': ["{static}", "{media}", "data:"],
'font-src': ["{static}"],
'media-src': ["{static}", "data:"],
@@ -417,6 +337,13 @@ class SecurityMiddleware(MiddlewareMixin):
h['style-src'] += ["'unsafe-inline'"]
h['connect-src'] += ["http://localhost:5173", "ws://localhost:5173"]
if hasattr(request, 'csp_nonce'):
nonce = f"'nonce-{request.csp_nonce}'"
h['script-src'].append(nonce)
if not settings.VITE_DEV_MODE:
# can't have 'unsafe-inline' and nonce at the same time
h['style-src'].append(nonce)
# Only include pay.google.com for wallet detection purposes on the Payment selection page
if (
url.url_name == "event.order.pay.change" or
@@ -429,9 +356,6 @@ class SecurityMiddleware(MiddlewareMixin):
if settings.LOG_CSP:
h['report-uri'] = ["/csp_report/"]
if request._csp_to_merge:
_merge_csp(h, request._csp_to_merge)
if 'Content-Security-Policy' in resp:
_merge_csp(h, _parse_csp(resp['Content-Security-Policy']))
@@ -497,16 +421,8 @@ class RejectInvalidInputMiddleware(MiddlewareMixin):
if "\x00" in request.META['QUERY_STRING'] or "%00" in request.META['QUERY_STRING']:
raise BadRequest("Invalid characters in input.")
if request.method in ('POST', 'PUT', 'PATCH') and request.content_type == "application/x-www-form-urlencoded":
try:
post_data = request.POST.lists()
except BadRequest:
# Reading request.POST wasn't possible, probably an invalid charset. Django will crash once we actually
# use request.POST, but if we don't, let's not crash it (required for some weird payment provider
# webhooks, e.g. computop).
pass
else:
if any("\x00" in value for key, value_list in post_data for value in value_list):
raise BadRequest("Invalid characters in input.")
if any("\x00" in value for key, value_list in request.POST.lists() for value in value_list):
raise BadRequest("Invalid characters in input.")
class CustomCommonMiddleware(CommonMiddleware):
@@ -1,48 +0,0 @@
# Generated by Django 5.2.12 on 2026-04-15 20:10
from decimal import Decimal
from django.db import migrations, models
import pretix.helpers.models
class Migration(migrations.Migration):
dependencies = [
('pretixbase', '0303_alter_order_organizer_alter_orderposition_organizer'),
]
operations = [
migrations.AlterField(
model_name='cartposition',
name='tax_rate',
field=pretix.helpers.models.NormalizedDecimalField(decimal_places=4, default=Decimal('0'), max_digits=7),
),
migrations.AlterField(
model_name='invoiceline',
name='tax_rate',
field=pretix.helpers.models.NormalizedDecimalField(decimal_places=4, default=Decimal('0'), max_digits=7),
),
migrations.AlterField(
model_name='orderfee',
name='tax_rate',
field=pretix.helpers.models.NormalizedDecimalField(decimal_places=4, max_digits=7),
),
migrations.AlterField(
model_name='orderposition',
name='tax_rate',
field=pretix.helpers.models.NormalizedDecimalField(decimal_places=4, max_digits=7),
),
migrations.AlterField(
model_name='transaction',
name='tax_rate',
field=pretix.helpers.models.NormalizedDecimalField(decimal_places=4, max_digits=7),
),
migrations.AlterField(
model_name='taxrule',
name='rate',
field=pretix.helpers.models.NormalizedDecimalField(decimal_places=4, max_digits=7),
),
]
@@ -1,91 +0,0 @@
# Generated by Django 5.2.12 on 2026-04-28 11:34
import logging
from django.db import IntegrityError, migrations, transaction
from django.db.models import Count, F
logger = logging.getLogger(__name__)
def fix_cross_organizer_eventmetavalues(apps, schema_editor):
EventMetaProperty = apps.get_model("pretixbase", "EventMetaProperty")
EventMetaValue = apps.get_model("pretixbase", "EventMetaValue")
cross_org_values = EventMetaValue.objects.filter(
event__organizer__pk__ne=F('property__organizer__pk')
).order_by('event__organizer__slug', 'event__slug')
for emv in cross_org_values:
logger.warning("%s", f"Fixing cross-organizer EventMetaValue: {emv.event.organizer.slug}/{emv.event.slug}")
logger.warning(" %s", f"{emv.property.name}({emv.property.id}@{emv.property.organizer.slug}) = {repr(emv.value)}")
try:
emv.property = emv.event.organizer.meta_properties.get(name=emv.property.name)
if EventMetaValue.objects.filter(event=emv.event, property=emv.property).exists():
correct = EventMetaValue.objects.get(event=emv.event, property=emv.property)
if correct.value != emv.value:
logger.warning(" %s", f"WARN: conflicting EventMetaValue with property in correct organizer already exists, deleting the cross-organizer one")
else:
logger.warning(" %s", f"OK: same-value EventMetaValue with property in correct organizer already exists, deleting the cross-organizer one")
logger.warning(" %s", f"keeping: {correct.property.name}({correct.property.id}@{correct.property.organizer.slug}) = {repr(correct.value)}")
emv.delete()
else:
logger.warning(" %s", f"OK: found existing EventMetaProperty in {emv.event.organizer.slug}, updating reference")
logger.warning(" %s", f"after: {emv.property.name}({emv.property.id}@{emv.property.organizer.slug}) = {repr(emv.value)}")
emv.save(update_fields=["property"])
except EventMetaProperty.DoesNotExist:
meta_prop = emv.property
meta_prop.pk = None
meta_prop.organizer = emv.event.organizer
meta_prop.filter_public = False
meta_prop.save(force_insert=True)
logger.warning(" %s", f"WARN: found no matching EventMetaProperty, creating")
logger.warning(" %s", f"after: {emv.property.name}({emv.property.id}@{emv.property.organizer.slug}) = {repr(emv.value)}")
emv.save(update_fields=["property"])
def make_eventmetaproperties_unique(apps, schema_editor):
EventMetaProperty = apps.get_model("pretixbase", "EventMetaProperty")
EventMetaValue = apps.get_model("pretixbase", "EventMetaValue")
duplicates = EventMetaProperty.objects.values('organizer', 'organizer__slug', 'name').annotate(count=Count('id')).filter(count__gt=1)
for dup in duplicates:
logger.warning("%s", f"Fixup duplicate property {dup['organizer__slug']} {dup['name']}")
props = list(EventMetaProperty.objects.filter(organizer=dup['organizer'], name=dup['name']))
target = props[0]
invalid = props[1:]
try:
with transaction.atomic():
affected = EventMetaValue.objects.filter(
event__organizer=dup['organizer'], property__in=invalid
).update(
property=target
)
logger.warning("%s", f" Switching {affected} value(s) over to {target.name}({target.id}@{target.organizer.slug})")
except IntegrityError as e:
logger.warning("%s", f" Failed to switch all value(s) over to {target.name}({target.id}@{target.organizer.slug})")
logger.warning("%s", f" {e}")
for prop in invalid:
newname = f'{prop.name}_DUPLICATE_{prop.id}'
logger.warning("%s", f" Renaming {prop.name}({prop.id}@{prop.organizer.slug}) to {newname}({prop.id}@{prop.organizer.slug})")
prop.name = newname
prop.filter_public = False
prop.save()
else:
for prop in invalid:
logger.warning("%s", f" Deleting {prop.name}({prop.id}@{prop.organizer.slug})")
prop.delete()
class Migration(migrations.Migration):
dependencies = [
("pretixbase", "0304_tax_rate_decimals"),
]
operations = [
migrations.RunPython(fix_cross_organizer_eventmetavalues, migrations.RunPython.noop),
migrations.RunPython(make_eventmetaproperties_unique, migrations.RunPython.noop),
]
@@ -1,17 +0,0 @@
# Generated by Django 5.2.12 on 2026-04-28 11:34
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("pretixbase", "0305_fixup_eventmetaproperties"),
]
operations = [
migrations.AlterUniqueTogether(
name="eventmetaproperty",
unique_together={("organizer", "name")},
),
]
+1 -11
View File
@@ -179,12 +179,6 @@ class EventMixin:
self.date_to.astimezone(tz), ("D" if short else "l")
)
def is_same_day(self):
if not self.date_to:
return True
else:
return self.date_from.astimezone(self.timezone).date() == self.date_to.astimezone(self.timezone).date()
def get_date_range_display(self, tz=None, force_show_end=False, as_html=False, try_to_show_times=False) -> str:
"""
Returns a formatted string containing the start date and the end date
@@ -238,9 +232,6 @@ class EventMixin:
@property
def timezone(self):
# If we get rid of the shim, verify that
# https://github.com/py-vobject/vobject/issues/117#issuecomment-5045645314
# has been released and included
return pytz_deprecation_shim.timezone(self.settings.timezone)
@property
@@ -658,7 +649,7 @@ class Event(EventMixin, LoggedModel):
is_remote = models.BooleanField(
default=False,
verbose_name=_("This event is remote or partially remote."),
help_text=_("This will be used to let users know if the event is in a different timezone, and to let us calculate the local time of a user."),
help_text=_("This will be used to let users know if the event is in a different timezone and lets us calculate users local times."),
)
geo_lat = models.FloatField(
verbose_name=_("Latitude"),
@@ -1860,7 +1851,6 @@ class EventMetaProperty(LoggedModel):
class Meta:
ordering = ("position", "name",)
unique_together = ('organizer', 'name')
@property
def choice_keys(self):
+1 -2
View File
@@ -49,7 +49,6 @@ from django_scopes import ScopedManager
from pretix.base.settings import COUNTRIES_WITH_STATE_IN_ADDRESS
from pretix.helpers.countries import FastCountryField
from pretix.helpers.models import NormalizedDecimalField
def invoice_filename(instance, filename: str) -> str:
@@ -451,7 +450,7 @@ class InvoiceLine(models.Model):
description = models.TextField()
gross_value = models.DecimalField(max_digits=13, decimal_places=2)
tax_value = models.DecimalField(max_digits=13, decimal_places=2, default=Decimal('0.00'))
tax_rate = NormalizedDecimalField(max_digits=7, decimal_places=4, default=Decimal('0'))
tax_rate = models.DecimalField(max_digits=7, decimal_places=2, default=Decimal('0.00'))
tax_name = models.CharField(max_length=190)
tax_code = models.CharField(max_length=190, null=True, blank=True)
subevent = models.ForeignKey('SubEvent', null=True, blank=True, on_delete=models.PROTECT)
+36
View File
@@ -885,6 +885,26 @@ class Item(LoggedModel):
return False
return True
def unavailability_reason(self, now_dt: datetime=None, has_voucher=False, subevent=None) -> Optional[str]:
now_dt = now_dt or time_machine_now()
subevent_item = subevent and subevent.item_overrides.get(self.pk)
if not self.active:
return 'active'
elif self.available_from and self.available_from > now_dt:
return 'available_from'
elif self.available_until and self.available_until < now_dt:
return 'available_until'
elif (self.require_voucher or self.hide_without_voucher) and not has_voucher:
return 'require_voucher'
elif subevent_item and subevent_item.available_from and subevent_item.available_from > now_dt:
return 'available_from'
elif subevent_item and subevent_item.available_until and subevent_item.available_until < now_dt:
return 'available_until'
elif self.hidden_if_item_available and self._dependency_available:
return 'hidden_if_item_available'
else:
return None
def _get_quotas(self, ignored_quotas=None, subevent=None):
check_quotas = set(getattr(
self, '_subevent_quotas', # Utilize cache in product list
@@ -1393,6 +1413,22 @@ class ItemVariation(models.Model):
return False
return True
def unavailability_reason(self, now_dt: datetime=None, has_voucher=False, subevent=None) -> Optional[str]:
now_dt = now_dt or time_machine_now()
subevent_var = subevent and subevent.var_overrides.get(self.pk)
if not self.active:
return 'active'
elif self.available_from and self.available_from > now_dt:
return 'available_from'
elif self.available_until and self.available_until < now_dt:
return 'available_until'
elif subevent_var and subevent_var.available_from and subevent_var.available_from > now_dt:
return 'available_from'
elif subevent_var and subevent_var.available_until and subevent_var.available_until < now_dt:
return 'available_until'
else:
return None
@property
def meta_data(self):
data = self.item.meta_data
+17 -43
View File
@@ -87,7 +87,6 @@ from pretix.base.timemachine import time_machine_now
from ...helpers import OF_SELF
from ...helpers.countries import CachedCountries, FastCountryField
from ...helpers.models import NormalizedDecimalField
from ...helpers.names import build_name
from ...testutils.middleware import debugflags_var
from ._transactions import (
@@ -508,20 +507,20 @@ class Order(LockModel, LoggedModel):
@classmethod
def annotate_overpayments(cls, qs, results=True, refunds=True, sums=False):
payment_sum = OrderPayment.objects.with_scopes_disabled().filter(
payment_sum = OrderPayment.objects.filter(
state__in=(OrderPayment.PAYMENT_STATE_CONFIRMED, OrderPayment.PAYMENT_STATE_REFUNDED),
order=OuterRef('pk')
).order_by().values('order').annotate(s=Sum('amount')).values('s')
refund_sum = OrderRefund.objects.with_scopes_disabled().filter(
refund_sum = OrderRefund.objects.filter(
state__in=(OrderRefund.REFUND_STATE_DONE, OrderRefund.REFUND_STATE_TRANSIT,
OrderRefund.REFUND_STATE_CREATED),
order=OuterRef('pk')
).order_by().values('order').annotate(s=Sum('amount')).values('s')
external_refund = OrderRefund.objects.with_scopes_disabled().filter(
external_refund = OrderRefund.objects.filter(
state=OrderRefund.REFUND_STATE_EXTERNAL,
order=OuterRef('pk')
)
pending_refund = OrderRefund.objects.with_scopes_disabled().filter(
pending_refund = OrderRefund.objects.filter(
state__in=(OrderRefund.REFUND_STATE_CREATED, OrderRefund.REFUND_STATE_TRANSIT),
order=OuterRef('pk')
)
@@ -2072,17 +2071,6 @@ class OrderPayment(models.Model):
"""
return '{}-P-{}'.format(self.order.code, self.local_id)
@property
def global_id(self):
"""
The global ID of this payment, constructed by the organizer slug, event slug, and the full id.
"""
return "{organizer}-{event}-{full_id}".format(
organizer=self.order.organizer.slug.upper(),
event=self.order.event.slug.upper(),
full_id=self.full_id,
)
def save(self, *args, **kwargs):
if not self.local_id:
self.local_id = (self.order.payments.aggregate(m=Max('local_id'))['m'] or 0) + 1
@@ -2283,17 +2271,6 @@ class OrderRefund(models.Model):
"""
return '{}-R-{}'.format(self.order.code, self.local_id)
@property
def global_id(self):
"""
The global ID of this refund, constructed by the organizer slug, event slug, and the full id.
"""
return "{organizer}-{event}-{full_id}".format(
organizer=self.order.organizer.slug.upper(),
event=self.order.event.slug.upper(),
full_id=self.full_id,
)
def save(self, *args, **kwargs):
if not self.local_id:
self.local_id = (self.order.refunds.aggregate(m=Max('local_id'))['m'] or 0) + 1
@@ -2308,12 +2285,9 @@ class OrderRefund(models.Model):
super().save(*args, **kwargs)
def ActivePositionManager(**scope):
class InnerClass(ScopedManager(**scope).__class__):
def get_queryset(self):
return super().get_queryset().filter(canceled=False)
return InnerClass()
class ActivePositionManager(ScopedManager(organizer='order__event__organizer').__class__):
def get_queryset(self):
return super().get_queryset().filter(canceled=False)
class OrderFee(RoundingCorrectionMixin, models.Model):
@@ -2380,8 +2354,8 @@ class OrderFee(RoundingCorrectionMixin, models.Model):
)
description = models.CharField(max_length=190, blank=True)
internal_type = models.CharField(max_length=255, blank=True)
tax_rate = NormalizedDecimalField(
max_digits=7, decimal_places=4,
tax_rate = models.DecimalField(
max_digits=7, decimal_places=2,
verbose_name=_('Tax rate')
)
tax_rule = models.ForeignKey(
@@ -2403,7 +2377,7 @@ class OrderFee(RoundingCorrectionMixin, models.Model):
canceled = models.BooleanField(default=False)
all = ScopedManager(organizer='order__event__organizer')
objects = ActivePositionManager(organizer='order__event__organizer')
objects = ActivePositionManager()
@property
def net_value(self):
@@ -2577,8 +2551,8 @@ class OrderPosition(AbstractPosition):
max_digits=13, decimal_places=2, null=True, blank=True,
)
tax_rate = NormalizedDecimalField(
max_digits=7, decimal_places=4,
tax_rate = models.DecimalField(
max_digits=7, decimal_places=2,
verbose_name=_('Tax rate')
)
tax_rule = models.ForeignKey(
@@ -2622,7 +2596,7 @@ class OrderPosition(AbstractPosition):
)
all = ScopedManager(organizer='organizer')
objects = ActivePositionManager(organizer='organizer')
objects = ActivePositionManager()
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
@@ -3096,8 +3070,8 @@ class Transaction(models.Model):
price_includes_rounding_correction = models.DecimalField(
max_digits=13, decimal_places=2, default=Decimal("0.00")
)
tax_rate = NormalizedDecimalField(
max_digits=7, decimal_places=4,
tax_rate = models.DecimalField(
max_digits=7, decimal_places=2,
verbose_name=_('Tax rate')
)
tax_rule = models.ForeignKey(
@@ -3212,8 +3186,8 @@ class CartPosition(AbstractPosition):
verbose_name=_("Limit for extending expiration date"),
null=True
)
tax_rate = NormalizedDecimalField(
max_digits=7, decimal_places=4, default=Decimal('0'),
tax_rate = models.DecimalField(
max_digits=7, decimal_places=2, default=Decimal('0.00'),
verbose_name=_('Tax rate')
)
tax_code = models.CharField(
+3 -4
View File
@@ -40,7 +40,6 @@ from pretix.base.decimal import round_decimal
from pretix.base.models.base import LoggedModel
from pretix.base.templatetags.money import money_filter
from pretix.helpers.countries import FastCountryField
from pretix.helpers.models import NormalizedDecimalField
class TaxedPrice:
@@ -336,9 +335,9 @@ class TaxRule(LoggedModel):
max_length=190,
choices=TAX_CODE_LISTS,
)
rate = NormalizedDecimalField(
max_digits=7,
decimal_places=4,
rate = models.DecimalField(
max_digits=10,
decimal_places=2,
validators=[
MaxValueValidator(
limit_value=Decimal("100.00"),
+2 -2
View File
@@ -936,7 +936,7 @@ class BasePaymentProvider:
"""
Will be called if the *event administrator* views the details of a payment.
It should return a SafeString containing HTML code, with information regarding the current payment
It should return HTML code containing information regarding the current payment
status and, if applicable, next steps.
The default implementation returns an empty string.
@@ -961,7 +961,7 @@ class BasePaymentProvider:
"""
Will be called if the *event administrator* views the details of a refund.
It should return a SafeString containing HTML code, with information regarding the current refund
It should return HTML code containing information regarding the current refund
status and, if applicable, next steps.
The default implementation returns an empty string.
-3
View File
@@ -245,9 +245,6 @@ def recv_classic(sender, **kwargs):
def assign_ticket_secret(event, position, force_invalidate_if_revokation_list_used=False, force_invalidate=False, save=True):
if position.pk and position.issued_gift_cards.exists():
return
gen = event.ticket_secret_generator
if gen.use_revocation_list and force_invalidate_if_revokation_list_used:
force_invalidate = True
+2 -2
View File
@@ -29,7 +29,7 @@ from typing import List
from django.utils.functional import cached_property
from pretix.base.models import CartPosition, ItemCategory, SalesChannel
from pretix.presale.productlist import prepare_item_list_for_shop
from pretix.presale.views.event import get_grouped_items
class DummyCategory:
@@ -162,7 +162,7 @@ class CrossSellingService:
]
def _prepare_items(self, subevent, items_qs, discount_info):
items, _btn = prepare_item_list_for_shop(
items, _btn = get_grouped_items(
self.event,
subevent=subevent,
voucher=None,
-3
View File
@@ -24,7 +24,6 @@ from typing import List, Optional
from dateutil.relativedelta import relativedelta
from django.core.exceptions import ValidationError
from django.db import transaction
from django.utils.formats import date_format
from django.utils.translation import gettext_lazy as _
@@ -97,8 +96,6 @@ def validate_memberships_in_order(customer: Customer, positions: List[AbstractPo
:param valid_from_not_chosen: Set to ``True`` to indicate that the customer is in an early step of the checkout flow
where the valid_from date is not selected yet. In this case, the valid_from date is not checked.
"""
if lock and not transaction.get_connection().in_atomic_block:
raise Exception('validate_memberships_in_order(lock=True) should only be called in atomic transaction!')
tz = event.timezone
applicable_positions = [
p for p in positions
+23 -52
View File
@@ -110,7 +110,6 @@ from pretix.celery_app import app
from pretix.helpers import OF_SELF
from pretix.helpers.models import modelcopy
from pretix.helpers.periodic import minimum_interval
from pretix.presale.productlist import prepare_item_list_for_shop
from pretix.testutils.middleware import debugflags_var
@@ -791,12 +790,6 @@ def _check_positions(event: Event, now_dt: datetime, time_machine_now_dt: dateti
[op.seat for op in sorted_positions if op.seat],
shared_lock_objects=[event]
)
elif any(cp.voucher and cp.voucher.budget for cp in sorted_positions):
# Voucher budgets are not guaranteed by the cart manager
lock_objects(
[op.voucher for op in sorted_positions if op.voucher and op.voucher.budget],
shared_lock_objects=[event]
)
q_avail = Counter()
v_avail = Counter()
@@ -1606,7 +1599,6 @@ class OrderChangeManager:
'seat_forbidden': gettext_lazy('The selected product does not allow to select a seat.'),
'tax_rule_country_blocked': gettext_lazy('The selected country is blocked by your tax rule.'),
'gift_card_change': gettext_lazy('You cannot change the price of a position that has been used to issue a gift card.'),
'gift_card_secret': gettext_lazy('You cannot change the ticket secret of a position that has been used to issue a gift card.'),
'max_items_per_product': ngettext_lazy(
"You cannot select more than %(max)s item of the product %(product)s.",
"You cannot select more than %(max)s items of the product %(product)s.",
@@ -1764,9 +1756,6 @@ class OrderChangeManager:
self._operations.append(self.RegenerateSecretOperation(position))
def change_ticket_secret(self, position: OrderPosition, new_secret: str):
if position.issued_gift_cards.exists():
raise OrderError(self.error_messages['gift_card_secret'])
self._operations.append(self.ChangeSecretOperation(position, new_secret))
def change_valid_from(self, position: OrderPosition, new_value: datetime):
@@ -1954,18 +1943,13 @@ class OrderChangeManager:
:param addons: A list of dictionaries with the keys ``"addon_to"``, ``"item"``, ``"variation"`` (all ID values),
``"count"``, and ``"price"``.
:param limit_main_positions: By default, the method works on all positions of the order. If you set this to a
:param limit_main_positions: By default, the method works on all methods of the order. If you set this to a
queryset or a list of positions, all other positions and their add-ons will be kept
untouched.
"""
if self._operations:
raise ValueError("Setting addons should be the first/only operation")
def _allowed_on_order_sales_channel(item_or_var, order):
return item_or_var.all_sales_channels or (
order.sales_channel.identifier in (s.identifier for s in item_or_var.limit_sales_channels.all())
)
# Prepare containers for min/max check of products
item_counts = Counter()
for p in self.order.positions.all():
@@ -2059,11 +2043,13 @@ class OrderChangeManager:
if not item.is_available() or (variation and not variation.is_available()):
raise OrderError(error_messages['unavailable'])
if not _allowed_on_order_sales_channel(item, self.order):
raise OrderError(error_messages['unavailable'])
if not item.all_sales_channels:
if self.order.sales_channel.identifier not in (s.identifier for s in item.limit_sales_channels.all()):
raise OrderError(error_messages['unavailable'])
if variation and not _allowed_on_order_sales_channel(variation, self.order):
raise OrderError(error_messages['unavailable'])
if variation and not variation.all_sales_channels:
if self.order.sales_channel.identifier not in (s.identifier for s in variation.limit_sales_channels.all()):
raise OrderError(error_messages['unavailable'])
if subevent and item.pk in subevent.item_overrides and not subevent.item_overrides[item.pk].is_available():
raise OrderError(error_messages['not_for_sale'])
@@ -2111,36 +2097,6 @@ class OrderChangeManager:
)
item_counts[item] += 1
def _addon_is_available(a):
# If an item is no longer available due to time, it should usually also be no longer
# user-removable, because e.g. the stock has already been ordered.
# We always set voucher=None because that's what's done when generating the form in
# OrderChangeMixin (vouchers for addons are not supported).
# This also prevents accidental removal through the UI because a hidden product will no longer
# be part of the input.
if not _allowed_on_order_sales_channel(a.item, self.order) or (
a.variation and not _allowed_on_order_sales_channel(a.variation, self.order)
):
return False
items, _ = prepare_item_list_for_shop(
self.order.event,
channel=self.order.sales_channel,
subevent=a.subevent,
voucher=None,
base_qs=Item.objects.filter(pk=a.item.pk),
allow_addons=True
)
if (not items) or items[0].current_unavailability_reason:
return False
if a.variation:
variations = [var for var in items[0].available_variations if var.pk == a.variation.pk]
if (not variations) or variations[0].current_unavailability_reason:
return False
return True
# Detect removed add-ons and create RemoveOperations
for cp, al in list(current_addons.items()):
for k, v in al.items():
@@ -2150,7 +2106,22 @@ class OrderChangeManager:
for a in current_addons[cp][k][:current_num - input_num]:
if a.canceled:
continue
if not _addon_is_available(a):
is_unavailable = (
# If an item is no longer available due to time, it should usually also be no longer
# user-removable, because e.g. the stock has already been ordered.
# We always pass has_voucher=True because if a product now requires a voucher, it usually does
# not mean it should be unremovable for others.
# This also prevents accidental removal through the UI because a hidden product will no longer
# be part of the input.
(a.variation and a.variation.unavailability_reason(has_voucher=True, subevent=a.subevent))
or (a.variation and not a.variation.all_sales_channels and not a.variation.limit_sales_channels.contains(self.order.sales_channel))
or a.item.unavailability_reason(has_voucher=True, subevent=a.subevent)
or (
not a.item.all_sales_channels and
not a.item.limit_sales_channels.contains(self.order.sales_channel)
)
)
if is_unavailable:
# "Re-select" add-on
selected_addons[cp.id, a.item.category_id][a.item_id, a.variation_id] += 1
continue
-18
View File
@@ -26,8 +26,6 @@ from babel.numbers import format_currency
from django import template
from django.conf import settings
from django.template.defaultfilters import floatformat
from django.utils import formats
from django.utils.safestring import mark_safe
from pretix.base.i18n import get_babel_locale
@@ -84,19 +82,3 @@ def money_numberfield_filter(value: Decimal, arg=''):
places = settings.CURRENCY_PLACES.get(arg, 2)
return str(value.quantize(Decimal('1') / 10 ** places, ROUND_HALF_UP))
@register.filter(is_safe=True)
def tax_rate_format(number):
"""
Display a Decimal to its significant decimal places, used for tax rates.
"""
assert isinstance(number, Decimal)
return mark_safe(
formats.number_format(
number.normalize(),
-number.as_tuple().exponent,
use_l10n=True,
force_grouping=False,
)
)
+6 -14
View File
@@ -19,10 +19,12 @@
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
# <https://www.gnu.org/licenses/>.
#
import json
import logging
import pathlib
import re
import secrets
from urllib.parse import urljoin
from urllib.request import urlopen
@@ -31,10 +33,6 @@ from django import template
from django.conf import settings
from django.utils.safestring import mark_safe
from pretix.base.middleware import (
add_to_response_csp_via_request, calculate_csp_hash,
)
register = template.Library()
LOGGER = logging.getLogger(__name__)
_MANIFEST = {}
@@ -236,16 +234,10 @@ def vite_importmap(context):
if not imports:
return ""
json_string = json.dumps({"imports": imports})
# Calculate hash and add it to the CSP info in the request, so that will be merged into the
# response header later on by the middleware
# Generate a nonce and store it on the request so the CSP middleware can allow it
nonce = secrets.token_urlsafe(16)
request = context.get('request')
if request:
csp_hash = calculate_csp_hash(json_string)
add_to_response_csp_via_request(request, {
'style-src': [csp_hash],
'script-src': [csp_hash],
})
request.csp_nonce = nonce
return f'<script type="importmap">{json_string}</script>'
return f'<script type="importmap" nonce="{nonce}">{json.dumps({"imports": imports})}</script>'
+1 -1
View File
@@ -27,11 +27,11 @@ from django.template import TemplateDoesNotExist, loader
from django.template.loader import get_template
from django.utils.functional import Promise
from django.utils.translation import gettext as _
from django.views.decorators.csrf import requires_csrf_token
from sentry_sdk import last_event_id
from pretix.base.i18n import language
from pretix.base.middleware import get_language_from_request
from pretix.multidomain.middlewares import requires_csrf_token
def csrf_failure(request, reason=""):
+9 -9
View File
@@ -197,10 +197,10 @@ class EventWizardBasicsForm(I18nModelForm):
'presale_end': SplitDateTimeField,
}
widgets = {
'date_from': SplitDateTimePickerWidget(without_seconds=True),
'date_to': SplitDateTimePickerWidget(attrs={'data-date-after': '#id_basics-date_from_0'}, without_seconds=True),
'presale_start': SplitDateTimePickerWidget(without_seconds=True),
'presale_end': SplitDateTimePickerWidget(attrs={'data-date-after': '#id_basics-presale_start_0'}, without_seconds=True),
'date_from': SplitDateTimePickerWidget(),
'date_to': SplitDateTimePickerWidget(attrs={'data-date-after': '#id_basics-date_from_0'}),
'presale_start': SplitDateTimePickerWidget(),
'presale_end': SplitDateTimePickerWidget(attrs={'data-date-after': '#id_basics-presale_start_0'}),
'slug': SlugWidget,
}
@@ -521,11 +521,11 @@ class EventUpdateForm(I18nModelForm):
'limit_sales_channels': SafeModelMultipleChoiceField,
}
widgets = {
'date_from': SplitDateTimePickerWidget(without_seconds=True),
'date_to': SplitDateTimePickerWidget(attrs={'data-date-after': '#id_date_from_0'}, without_seconds=True),
'date_admission': SplitDateTimePickerWidget(attrs={'data-date-default': '#id_date_from_0'}, without_seconds=True),
'presale_start': SplitDateTimePickerWidget(without_seconds=True),
'presale_end': SplitDateTimePickerWidget(attrs={'data-date-after': '#id_presale_start_0'}, without_seconds=True),
'date_from': SplitDateTimePickerWidget(),
'date_to': SplitDateTimePickerWidget(attrs={'data-date-after': '#id_date_from_0'}),
'date_admission': SplitDateTimePickerWidget(attrs={'data-date-default': '#id_date_from_0'}),
'presale_start': SplitDateTimePickerWidget(),
'presale_end': SplitDateTimePickerWidget(attrs={'data-date-after': '#id_presale_start_0'}),
}
+2 -91
View File
@@ -39,7 +39,6 @@ from urllib.parse import urlencode
from django import forms
from django.apps import apps
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.db.models import (
Count, Exists, F, Max, Model, OrderBy, OuterRef, Q, QuerySet,
)
@@ -60,7 +59,7 @@ from pretix.base.models import (
Gate, Invoice, InvoiceAddress, Item, Order, OrderPayment, OrderPosition,
OrderRefund, Organizer, OutgoingMail, Question, QuestionAnswer, Quota,
SalesChannel, SubEvent, SubEventMetaValue, Team, TeamAPIToken, TeamInvite,
User, Voucher,
Voucher,
)
from pretix.base.signals import register_payment_providers
from pretix.base.timeframes import (
@@ -771,7 +770,7 @@ class EventOrderExpertFilterForm(EventOrderFilterForm):
)
elif q.type == Question.TYPE_TIME:
self.fields[fname] = forms.TimeField(
widget=TimePickerWidget(without_seconds=True),
widget=TimePickerWidget(time_format=get_format_without_seconds('TIME_INPUT_FORMATS')),
help_text=_('Exact matches only'),
**kwargs,
)
@@ -3008,91 +3007,3 @@ class OutgoingMailFilterForm(FilterForm):
qs = qs.order_by("-created", "-pk")
return qs
class LogFilterForm(FilterForm):
source = forms.ChoiceField(
label=_('Source'),
choices=[
('', _('All sources')),
('team', _('Team actions')),
('customer', _('Customer actions')),
('device', _('Device actions')),
],
required=False
)
device = SafeModelChoiceField(
label=_('Device'),
empty_label=_('All devices'),
queryset=Device.objects.none(),
required=False
)
user_email = forms.EmailField(
label=_('User email'),
widget=forms.EmailInput(
attrs={"placeholder": _('All users')}
),
required=False
)
action_type = forms.CharField(
widget=forms.HiddenInput,
required=False,
)
content_type = forms.ModelChoiceField(
queryset=ContentType.objects.all(),
widget=forms.HiddenInput,
required=False,
)
object = forms.IntegerField(
widget=forms.HiddenInput,
required=False
)
def __init__(self, *args, **kwargs):
self.organizer = kwargs.pop('organizer')
super().__init__(*args, **kwargs)
self.fields['device'].queryset = self.organizer.devices.all().order_by('device_id')
self.fields['device'].widget = Select2(
attrs={
'data-model-select2': 'generic',
'data-select2-url': reverse('control:organizer.devices.select2', kwargs={
'organizer': self.organizer.slug,
}),
'data-placeholder': _('All devices'),
}
)
self.fields['device'].widget.choices = self.fields['device'].choices
self.fields['device'].label = _('Device')
def filter_qs(self, qs):
fdata = self.cleaned_data
if fdata.get('source') == 'team':
qs = qs.filter(user__isnull=False)
elif fdata.get('source') == 'device':
qs = qs.filter(device__isnull=False)
elif fdata.get('source') == 'customer':
qs = qs.filter(user__isnull=True, device__isnull=True)
if fdata.get('device'):
qs = qs.filter(device_id=fdata['device'].pk)
if fdata.get('action_type'):
qs = qs.filter(action_type__in=fdata['action_type'].split(','))
if fdata.get('user_email'):
try:
user = User.objects.get(email=fdata['user_email'].lower())
qs = qs.filter(user=user)
except User.DoesNotExist:
# Do not actively leak info that this user does not exist. Yes, this will likely have a
# timing attack possibility, but with the magic that database query planners do,
# it's probably impossible to avoid that.
qs = qs.none()
if fdata.get('content_type'):
qs = qs.filter(content_type=fdata.get('content_type'))
if fdata.get('object'):
qs = qs.filter(object_id=fdata.get('object'))
return qs
+4 -4
View File
@@ -246,8 +246,8 @@ class QuestionForm(I18nModelForm):
'valid_string_length_max',
]
widgets = {
'valid_datetime_min': SplitDateTimePickerWidget(without_seconds=True),
'valid_datetime_max': SplitDateTimePickerWidget(without_seconds=True),
'valid_datetime_min': SplitDateTimePickerWidget(),
'valid_datetime_max': SplitDateTimePickerWidget(),
'valid_date_min': DatePickerWidget(),
'valid_date_max': DatePickerWidget(),
'items': forms.CheckboxSelectMultiple(
@@ -1427,6 +1427,6 @@ class ItemProgramTimeForm(I18nModelForm):
'end': forms.SplitDateTimeField,
}
widgets = {
'start': SplitDateTimePickerWidget(without_seconds=True),
'end': SplitDateTimePickerWidget(without_seconds=True),
'start': SplitDateTimePickerWidget(),
'end': SplitDateTimePickerWidget(),
}
+3 -1
View File
@@ -562,7 +562,9 @@ class OrderPositionChangeForm(forms.Form):
if instance.addon_to_id:
del self.fields['operation_split']
if not instance.seat and not instance._seat_allowed:
if not instance.seat and not (
instance.item.seat_category_mappings.filter(subevent=instance.subevent).exists()
):
del self.fields['seat']
choices = [
+6 -13
View File
@@ -39,7 +39,6 @@ from pretix.base.reldate import RelativeDateTimeField, RelativeDateWrapper
from pretix.base.templatetags.money import money_filter
from pretix.control.forms import SplitDateTimeField, SplitDateTimePickerWidget
from pretix.control.forms.rrule import RRuleForm
from pretix.helpers.i18n import get_javascript_format_without_seconds
from pretix.helpers.money import change_decimal_field
@@ -81,11 +80,11 @@ class SubEventForm(I18nModelForm):
'presale_end': SplitDateTimeField,
}
widgets = {
'date_from': SplitDateTimePickerWidget(without_seconds=True),
'date_to': SplitDateTimePickerWidget(attrs={'data-date-after': '#id_date_from_0'}, without_seconds=True),
'date_admission': SplitDateTimePickerWidget(attrs={'data-date-after': '#id_date_from_0'}, without_seconds=True),
'presale_start': SplitDateTimePickerWidget(without_seconds=True),
'presale_end': SplitDateTimePickerWidget(attrs={'data-date-after': '#id_presale_start_0'}, without_seconds=True),
'date_from': SplitDateTimePickerWidget(),
'date_to': SplitDateTimePickerWidget(attrs={'data-date-after': '#id_date_from_0'}),
'date_admission': SplitDateTimePickerWidget(attrs={'data-date-after': '#id_date_from_0'}),
'presale_start': SplitDateTimePickerWidget(),
'presale_end': SplitDateTimePickerWidget(attrs={'data-date-after': '#id_presale_start_0'}),
}
@@ -163,7 +162,7 @@ class SubEventBulkEditForm(I18nModelForm):
self.fields[k + '_time'] = forms.TimeField(
label=self._meta.model._meta.get_field(k).verbose_name,
help_text=self._meta.model._meta.get_field(k).help_text,
widget=TimePickerWidget(without_seconds=True),
widget=TimePickerWidget(),
required=False,
)
@@ -507,12 +506,6 @@ class TimeForm(forms.Form):
required=False
)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['time_from'].widget.attrs['data-format'] = get_javascript_format_without_seconds("TIME_INPUT_FORMATS")
self.fields['time_to'].widget.attrs['data-format'] = get_javascript_format_without_seconds("TIME_INPUT_FORMATS")
self.fields['time_admission'].widget.attrs['data-format'] = get_javascript_format_without_seconds("TIME_INPUT_FORMATS")
TimeFormSet = formset_factory(
TimeForm,
+13 -21
View File
@@ -33,7 +33,6 @@
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under the License.
import functools
from collections import defaultdict
from datetime import datetime
from decimal import Decimal
@@ -70,15 +69,6 @@ OVERVIEW_BANLIST = [
]
@functools.lru_cache(maxsize=32)
def object_id_to_string(model_class, **kwargs):
# The cache is thread-local and persists requests, but it's small enough that we can accept that
try:
return str(model_class.objects.get(**kwargs))
except model_class.DoesNotExist:
return "?"
class OrderChangeLogEntryType(OrderLogEntryType):
prefix = _('The order has been changed:')
@@ -103,10 +93,10 @@ class OrderItemChanged(OrderChangeLogEntryType):
def display_prefixed(self, event: Event, logentry: LogEntry, data):
old_item = str(event.items.get(pk=data['old_item']))
if data['old_variation']:
old_item += ' - ' + str(object_id_to_string(ItemVariation, item__event_id=event.pk, pk=data['old_variation']))
old_item += ' - ' + str(ItemVariation.objects.get(item__event=event, pk=data['old_variation']))
new_item = str(event.items.get(pk=data['new_item']))
if data['new_variation']:
new_item += ' - ' + str(object_id_to_string(ItemVariation, item__event_id=event.pk, pk=data['new_variation']))
new_item += ' - ' + str(ItemVariation.objects.get(item__event=event, pk=data['new_variation']))
return _('Position #{posid}: {old_item} ({old_price}) changed to {new_item} ({new_price}).').format(
posid=data.get('positionid', '?'),
old_item=old_item, new_item=new_item,
@@ -163,14 +153,14 @@ class OrderTaxRuleChanged(OrderChangeLogEntryType):
if 'positionid' in data:
return _('Tax rule of position #{posid} changed from {old_rule} to {new_rule}.').format(
posid=data.get('positionid', '?'),
old_rule=object_id_to_string(TaxRule, pk=data['old_taxrule']) if data['old_taxrule'] else '',
new_rule=object_id_to_string(TaxRule, pk=data['new_taxrule']),
old_rule=TaxRule.objects.get(pk=data['old_taxrule']) if data['old_taxrule'] else '',
new_rule=TaxRule.objects.get(pk=data['new_taxrule']),
)
elif 'fee' in data:
return _('Tax rule of fee #{fee} changed from {old_rule} to {new_rule}.').format(
fee=data.get('fee', '?'),
old_rule=object_id_to_string(TaxRule, pk=data['old_taxrule']) if data['old_taxrule'] else '',
new_rule=object_id_to_string(TaxRule, pk=data['new_taxrule']),
old_rule=TaxRule.objects.get(pk=data['old_taxrule']) if data['old_taxrule'] else '',
new_rule=TaxRule.objects.get(pk=data['new_taxrule']),
)
@@ -214,7 +204,7 @@ class OrderCanceled(OrderChangeLogEntryType):
def display_prefixed(self, event: Event, logentry: LogEntry, data):
old_item = str(event.items.get(pk=data['old_item']))
if data['old_variation']:
old_item += ' - ' + object_id_to_string(ItemVariation, pk=data['old_variation'])
old_item += ' - ' + str(ItemVariation.objects.get(pk=data['old_variation']))
return _('Position #{posid} ({old_item}, {old_price}) canceled.').format(
posid=data.get('positionid', '?'),
old_item=old_item,
@@ -229,7 +219,7 @@ class OrderPositionAdded(OrderChangeLogEntryType):
def display_prefixed(self, event: Event, logentry: LogEntry, data):
item = str(event.items.get(pk=data['item']))
if data['variation']:
item += ' - ' + object_id_to_string(ItemVariation, item__event_id=event.pk, pk=data['variation'])
item += ' - ' + str(ItemVariation.objects.get(item__event=event, pk=data['variation']))
if data['addon_to']:
addon_to = OrderPosition.objects.get(order__event=event, pk=data['addon_to'])
return _('Position #{posid} created: {item} ({price}) as an add-on to position #{addon_to}.').format(
@@ -293,7 +283,7 @@ class OrderChangedSplit(OrderChangeLogEntryType):
def display_prefixed(self, event: Event, logentry: LogEntry, data):
old_item = str(event.items.get(pk=data['old_item']))
if data['old_variation']:
old_item += ' - ' + object_id_to_string(ItemVariation, pk=data['old_variation'])
old_item += ' - ' + str(ItemVariation.objects.get(pk=data['old_variation']))
url = reverse('control:event.order', kwargs={
'event': event.slug,
'organizer': event.organizer.slug,
@@ -349,7 +339,6 @@ class OrderChangedSplitFrom(OrderLogEntryType):
'pretix.event.checkin.reverted': _('The check-in of position #{posid} on list "{list}" has been reverted.'),
})
class CheckinErrorLogEntryType(OrderLogEntryType):
def display(self, logentry: LogEntry, data):
return self.display_plain(self.plain, logentry, data)
@@ -364,7 +353,10 @@ class CheckinErrorLogEntryType(OrderLogEntryType):
event = logentry.event
if 'list' in data and event:
data['list'] = object_id_to_string(CheckinList, event_id=event.id, pk=data['list'])
try:
data['list'] = event.checkin_lists.get(pk=data.get('list')).name
except CheckinList.DoesNotExist:
data['list'] = _("(unknown)")
else:
data['list'] = _("(unknown)")
+2 -2
View File
@@ -141,7 +141,7 @@ event_dashboard_widgets = EventPluginSignal()
This signal is sent out to include widgets in the event dashboard. Receivers
should return a list of dictionaries, where each dictionary can have the keys:
* content (SafeString, containing HTML)
* content (str, containing HTML)
* display_size (str, one of "full" (whole row), "big" (half a row) or "small"
(quarter of a row). May be ignored on small displays, default is "small")
* priority (int, used for ordering, higher comes first, default is 1)
@@ -158,7 +158,7 @@ Arguments: 'user'
This signal is sent out to include widgets in the personal user dashboard. Receivers
should return a list of dictionaries, where each dictionary can have the keys:
* content (SafeString, containing HTML)
* content (str, containing HTML)
* display_size (str, one of "full" (whole row), "big" (half a row) or "small"
(quarter of a row). May be ignored on small displays, default is "small")
* priority (int, used for ordering, higher comes first, default is 1)
@@ -3,7 +3,6 @@
{% load i18n %}
{% load static %}
{% load compress %}
{% load escapejson %}
{% block content %}
<form class="form-signin" action="" method="post" id="webauthn-form">
{% csrf_token %}
@@ -31,7 +30,8 @@
</form>
{% if jsondata %}
<script type="text/json" id="webauthn-login">
{{ jsondata|escapejson }}
{{ jsondata|safe }}
</script>
{% endif %}
{% compress js %}
@@ -28,7 +28,7 @@
{% if w.lazy %}
<span class="fa fa-cog fa-4x"></span>
{% else %}
{{ w.content }}
{{ w.content|safe }}
{% endif %}
</div>
</div>
@@ -51,7 +51,7 @@
{% if w.lazy %}
<span class="fa fa-cog fa-4x"></span>
{% else %}
{{ w.content }}
{{ w.content|safe }}
{% endif %}
</div>
</div>
@@ -72,7 +72,7 @@
{% if w.lazy %}
<span class="fa fa-cog fa-4x"></span>
{% else %}
{{ w.content }}
{{ w.content|safe }}
{% endif %}
</div>
</div>
@@ -94,7 +94,7 @@
{% if w.lazy %}
<span class="fa fa-cog fa-4x"></span>
{% else %}
{{ w.content }}
{{ w.content|safe }}
{% endif %}
</a>
{% else %}
@@ -102,7 +102,7 @@
{% if w.lazy %}
<span class="fa fa-cog fa-4x"></span>
{% else %}
{{ w.content }}
{{ w.content|safe }}
{% endif %}
</div>
{% endif %}
@@ -50,46 +50,6 @@
{% endblocktrans %}
</div>
{% endif %}
{% if dkim_warning %}
<div class="alert alert-danger">
<p>
{{ dkim_warning }}
</p>
<p>
{% trans "Your new DKIM record should be set up as a CNAME record like this:" %}
</p>
<pre><code>{{ dkim_hostname }} CNAME {{ dkim_cname }}</code></pre>
<p>
{% trans "Please keep in mind that updates to DNS might require multiple hours to take effect." %}
</p>
</div>
{% elif dkim_cname %}
<div class="alert alert-success">
{% blocktrans trimmed %}
We found a DKIM record on your domain for this system. Great!
{% endblocktrans %}
</div>
{% endif %}
{% if dmarc_warning %}
<div class="alert alert-danger">
<p>
{{ dmarc_warning }}
</p>
<p>
{% trans "Your new DMARC record could look like this:" %}
</p>
<pre><code>_dmarc.{{ hostname }} TXT "v=DMARC1; p=quarantine; sp=none; adkim=r; aspf=r;"</code></pre>
<p>
{% trans "Please keep in mind that updates to DNS might require multiple hours to take effect." %}
</p>
</div>
{% elif dkim_cname %}
<div class="alert alert-success">
{% blocktrans trimmed %}
We found a DMARC record on your domain for this system. Great!
{% endblocktrans %}
</div>
{% endif %}
{% if verification %}
<h3>{% trans "Verification" %}</h3>
<p>
@@ -110,7 +70,7 @@
</div>
</div>
{% if spf_warning or dkim_warning or dmarc_warning %}
{% if spf_warning %}
<div class="form-group submit-group">
<a href="" class="btn btn-default btn-save">
{% trans "Cancel" %}
@@ -1,58 +0,0 @@
{% load i18n %}
{% if has_overpaid_orders %}
<div class="alert alert-warning">
{% blocktrans trimmed %}
This event contains <strong>overpaid orders</strong>, for example due to duplicate payment attempts.
You should review the cases and consider refunding the overpaid amount to the user.
{% endblocktrans %}
<a href="{% url "control:event.orders" event=request.event.slug organizer=request.event.organizer.slug %}?status=overpaid"
class="btn btn-primary">{% trans "Show overpaid orders" %}</a>
</div>
{% endif %}
{% if has_pending_refunds %}
<div class="alert alert-warning">
{% blocktrans trimmed %}
This event contains <strong>pending refunds</strong> that you should take care of.
{% endblocktrans %}
<a href="{% url "control:event.orders.refunds" event=request.event.slug organizer=request.event.organizer.slug %}"
class="btn btn-primary">{% trans "Show pending refunds" %}</a>
</div>
{% endif %}
{% if has_cancellation_requests %}
<div class="alert alert-warning">
{% blocktrans trimmed %}
This event contains <strong>requested cancellations</strong> that you should take care of.
{% endblocktrans %}
<a href="{% url "control:event.orders" event=request.event.slug organizer=request.event.organizer.slug %}?status=rc"
class="btn btn-primary">{% trans "Show orders requesting cancellation" %}</a>
</div>
{% endif %}
{% if has_pending_approvals %}
<div class="alert alert-warning">
{% blocktrans trimmed %}
This event contains <strong>pending approvals</strong> that you should take care of.
{% endblocktrans %}
<a href="{% url "control:event.orders" event=request.event.slug organizer=request.event.organizer.slug %}?status=pa"
class="btn btn-primary">{% trans "Show orders pending approval" %}</a>
</div>
{% endif %}
{% if has_pending_orders_with_full_payment %}
<div class="alert alert-warning">
{% blocktrans trimmed %}
This event contains <strong>fully paid orders</strong> that are not marked as paid, probably
because no quota was left at the time their payment arrived. You should review the cases and consider
either refunding the customer or creating more space.
{% endblocktrans %}
<a href="{% url "control:event.orders" event=request.event.slug organizer=request.event.organizer.slug %}?status=pendingpaid"
class="btn btn-primary">{% trans "Show affected orders" %}</a>
</div>
{% endif %}
{% if has_sync_problems %}
<div class="alert alert-warning">
{% blocktrans trimmed %}
Orders in this event could not be <strong>synced to an external system</strong> as configured.
{% endblocktrans %}
<a href="{% url "control:event.datasync.failedjobs" event=request.event.slug organizer=request.event.organizer.slug %}"
class="btn btn-primary">{% trans "Show sync problems" %}</a>
</div>
{% endif %}
@@ -14,7 +14,6 @@
{% else %}
{{ request.event.get_date_range_display }}
{% endif %}
<span id="warnings_loading" class="fa fa-cog fa-spin"></span>
</small>
</h1>
<div class="helper-space-below">
@@ -32,7 +31,63 @@
</div>
<div class="clearfix"></div>
</div>
<div id="warnings_target"></div>
{% if has_overpaid_orders %}
<div class="alert alert-warning">
{% blocktrans trimmed %}
This event contains <strong>overpaid orders</strong>, for example due to duplicate payment attempts.
You should review the cases and consider refunding the overpaid amount to the user.
{% endblocktrans %}
<a href="{% url "control:event.orders" event=request.event.slug organizer=request.event.organizer.slug %}?status=overpaid"
class="btn btn-primary">{% trans "Show overpaid orders" %}</a>
</div>
{% endif %}
{% if has_pending_refunds %}
<div class="alert alert-warning">
{% blocktrans trimmed %}
This event contains <strong>pending refunds</strong> that you should take care of.
{% endblocktrans %}
<a href="{% url "control:event.orders.refunds" event=request.event.slug organizer=request.event.organizer.slug %}"
class="btn btn-primary">{% trans "Show pending refunds" %}</a>
</div>
{% endif %}
{% if has_cancellation_requests %}
<div class="alert alert-warning">
{% blocktrans trimmed %}
This event contains <strong>requested cancellations</strong> that you should take care of.
{% endblocktrans %}
<a href="{% url "control:event.orders" event=request.event.slug organizer=request.event.organizer.slug %}?status=rc"
class="btn btn-primary">{% trans "Show orders requesting cancellation" %}</a>
</div>
{% endif %}
{% if has_pending_approvals %}
<div class="alert alert-warning">
{% blocktrans trimmed %}
This event contains <strong>pending approvals</strong> that you should take care of.
{% endblocktrans %}
<a href="{% url "control:event.orders" event=request.event.slug organizer=request.event.organizer.slug %}?status=pa"
class="btn btn-primary">{% trans "Show orders pending approval" %}</a>
</div>
{% endif %}
{% if has_pending_orders_with_full_payment %}
<div class="alert alert-warning">
{% blocktrans trimmed %}
This event contains <strong>fully paid orders</strong> that are not marked as paid, probably
because no quota was left at the time their payment arrived. You should review the cases and consider
either refunding the customer or creating more space.
{% endblocktrans %}
<a href="{% url "control:event.orders" event=request.event.slug organizer=request.event.organizer.slug %}?status=pendingpaid"
class="btn btn-primary">{% trans "Show affected orders" %}</a>
</div>
{% endif %}
{% if has_sync_problems %}
<div class="alert alert-warning">
{% blocktrans trimmed %}
Orders in this event could not be <strong>synced to an external system</strong> as configured.
{% endblocktrans %}
<a href="{% url "control:event.datasync.failedjobs" event=request.event.slug organizer=request.event.organizer.slug %}"
class="btn btn-primary">{% trans "Show sync problems" %}</a>
</div>
{% endif %}
{% eventsignal request.event "pretix.control.signals.event_dashboard_top" request=request %}
{% if request.event.has_subevents %}
@@ -51,7 +106,7 @@
{% if w.lazy %}
<span class="fa fa-cog fa-4x"></span>
{% else %}
{{ w.content }}
{{ w.content|safe }}
{% endif %}
</a>
{% elif w.link %}
@@ -59,7 +114,7 @@
{% if w.lazy %}
<span class="fa fa-cog fa-4x´"></span>
{% else %}
{{ w.content }}
{{ w.content|safe }}
{% endif %}
</a>
{% else %}
@@ -67,7 +122,7 @@
{% if w.lazy %}
<span class="fa fa-cog fa-4x"></span>
{% else %}
{{ w.content }}
{{ w.content|safe }}
{% endif %}
</div>
{% endif %}
@@ -1,12 +1,41 @@
{% extends "pretixcontrol/items/base.html" %}
{% load i18n %}
{% load static %}
{% load bootstrap3 %}
{% load icon %}
{% block title %}{% trans "Event logs" %}{% endblock %}
{% block inside %}
<h1>{% trans "Event logs" %}</h1>
{% include "pretixcontrol/fragment_log_filter_form.html" %}
<form class="form-inline helper-display-inline" action="" method="get">
<input type="hidden" name="content_type" value="{{ request.GET.content_type }}">
<input type="hidden" name="object" value="{{ request.GET.object }}">
<p>
<select name="user" class="form-control">
<option value="">{% trans "All actions" %}</option>
<option value="yes" {% if request.GET.user == "yes" %}selected="selected"{% endif %}>
{% trans "Team actions" %}
</option>
<option value="no" {% if request.GET.user == "no" %}selected="selected"{% endif %}>
{% trans "Customer actions" %}
</option>
{% for up in userlist %}
{% if up.user__id %}
<option value="{{ up.user__id }}"
{% if request.GET.user == up.user__id %}selected="selected"{% endif %}>
{{ up.user__email }}
</option>
{% endif %}
{% endfor %}
{% for d in devicelist %}
{% if d.device__id %}
<option value="d-{{ d.device__id }}"
{% if "d-" in request.GET.user and request.GET.user|slice:"2:" == d.device__id|slugify %}selected="selected"{% endif %}>
{{ d.device__name }}
</option>
{% endif %}
{% endfor %}
</select>
<button class="btn btn-primary" type="submit">{% trans "Filter" %}</button>
</p>
</form>
<ul class="list-group">
{% for log in logs %}
<li class="list-group-item logentry">
@@ -66,5 +95,5 @@
</div>
{% endfor %}
</ul>
{% include "pretixcontrol/pagination_huge.html" %}
{% include "pretixcontrol/pagination.html" %}
{% endblock %}
@@ -12,7 +12,7 @@
<table class="table table-payment-providers">
<tbody>
{% for provider in providers %}
<tr{% if provider.highlight %} class="success-left"{% endif %}>
<tr>
<td>
<strong>{{ provider.verbose_name }}</strong>
</td>
@@ -56,7 +56,7 @@
<td colspan="4">
<br>
{% url "control:event.settings.plugins" event=request.event.slug organizer=request.organizer.slug as plugin_settings_url %}
<a href="{{ plugin_settings_url }}?go=payment#tab-0-1-open" class="btn btn-default">
<a href="{{ plugin_settings_url }}#tab-0-1-open" class="btn btn-default">
<i class="fa fa-plus"></i> {% trans "Enable additional payment plugins" %}
</a>
</td>
@@ -28,7 +28,6 @@
</div>
<form action="" method="post" class="form-horizontal form-plugins">
{% csrf_token %}
<input type="hidden" name="go" value="{{ request.GET.go }}">
<div id="plugin_search_results" class="panel panel-default collapse">
<div class="panel-heading">
<button type="button" class="close" aria-label="Close"><span aria-hidden="true">×</span></button>
@@ -1,38 +0,0 @@
{% load i18n %}
{% load bootstrap3 %}
{% load icon %}
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">
{% trans "Filter" %}
</h3>
</div>
<form class="panel-body filter-form" action="" method="get">
<div class="row">
<div class="col-md-3 col-xs-6">
{% bootstrap_field filter_form.source %}
</div>
<div class="col-md-3 col-xs-6">
{% bootstrap_field filter_form.device %}
</div>
<div class="col-md-3 col-xs-6">
{% bootstrap_field filter_form.user_email %}
</div>
</div>
{{ filter_form.action_type }}
{{ filter_form.content_type }}
{{ filter_form.object }}
{% if filter_form.is_valid and filter_form.cleaned_data.action_type %}
{% icon "filter" %} <code>{{ filter_form.cleaned_data.action_type }}</code>
{% endif %}
{% if filter_form.is_valid and filter_form.cleaned_data.content_type and filter_form.cleaned_data.object %}
{% icon "filter" %} {% trans "Specific object selected" %}
{% endif %}
<div class="text-right flip">
<button class="btn btn-primary btn-lg" type="submit">
<span class="fa fa-filter"></span>
{% trans "Filter" %}
</button>
</div>
</form>
</div>
@@ -156,11 +156,11 @@
<br/>
<small class="text-muted">
{% if not i.tax_rule.price_includes_tax %}
{% blocktrans trimmed with rate=i.tax_rule.rate|tax_rate_format taxname=i.tax_rule.name %}
{% blocktrans trimmed with rate=i.tax_rule.rate|floatformat:-2 taxname=i.tax_rule.name %}
<strong>plus</strong> {{ rate }}% {{ taxname }}
{% endblocktrans %}
{% else %}
{% blocktrans trimmed with rate=i.tax_rule.rate|tax_rate_format taxname=i.tax_rule.name|default:s_taxes %}
{% blocktrans trimmed with rate=i.tax_rule.rate|floatformat:-2 taxname=i.tax_rule.name|default:s_taxes %}
incl. {{ rate }}% {{ taxname }}
{% endblocktrans %}
{% endif %}
@@ -2,7 +2,6 @@
{% load i18n %}
{% load bootstrap3 %}
{% load money %}
{% load wrap_in %}
{% block title %}
{% trans "Cancel order" %}
{% endblock %}
@@ -27,7 +26,7 @@
{% if form.cancellation_fee %}
{% if fee %}
{% with fee|money:request.event.currency as f %}
<p>{% blocktrans trimmed with fee=f|wrap_in:"strong" %}
<p>{% blocktrans trimmed with fee="<strong>"|add:f|add:"</strong>"|safe %}
The configured cancellation fee for a self-service cancellation would be {{ fee }} for this
order, but for a cancellation performed by you, you need to set the cancellation fee here:
{% endblocktrans %}</p>
@@ -284,14 +284,6 @@
</div>
<div class="col-sm-4">
{% bootstrap_field position.form.operation_secret layout='inline' %}
{% if position.issued_gift_cards.exists %}
<div class="alert alert-info">
{% blocktrans trimmed %}
Ticket secrets of order positions that have been used to issue a gift card can not
be changed. Only the link will be changed in this case.
{% endblocktrans %}
</div>
{% endif %}
</div>
</div>
@@ -705,7 +705,7 @@
{% if line.tax_rate %}
<br/>
<small>
{% blocktrans trimmed with rate=line.tax_rate|tax_rate_format taxname=line.tax_rule.name|default:s_taxes %}
{% blocktrans trimmed with rate=line.tax_rate|floatformat:-2 taxname=line.tax_rule.name|default:s_taxes %}
<strong>plus</strong> {{ rate }}% {{ taxname }}
{% endblocktrans %}
</small>
@@ -715,7 +715,7 @@
{% if line.tax_rate and line.price %}
<br/>
<small>
{% blocktrans trimmed with rate=line.tax_rate|tax_rate_format taxname=line.tax_rule.name|default:s_taxes %}
{% blocktrans trimmed with rate=line.tax_rate|floatformat:-2 taxname=line.tax_rule.name|default:s_taxes %}
incl. {{ rate }}% {{ taxname }}
{% endblocktrans %}
</small>
@@ -755,7 +755,7 @@
{% if fee.tax_rate %}
<br/>
<small>
{% blocktrans trimmed with rate=fee.tax_rate|tax_rate_format taxname=fee.tax_rule.name|default:s_taxes %}
{% blocktrans trimmed with rate=fee.tax_rate|floatformat:-2 taxname=fee.tax_rule.name|default:s_taxes %}
<strong>plus</strong> {{ rate }}% {{ taxname }}
{% endblocktrans %}
</small>
@@ -765,7 +765,7 @@
{% if fee.tax_rate %}
<br/>
<small>
{% blocktrans trimmed with rate=fee.tax_rate|tax_rate_format taxname=fee.tax_rule.name|default:s_taxes %}
{% blocktrans trimmed with rate=fee.tax_rate|floatformat:-2 taxname=fee.tax_rule.name|default:s_taxes %}
incl. {{ rate }}% {{ taxname }}
{% endblocktrans %}
</small>
@@ -833,7 +833,7 @@
<strong>{% trans "Pending total" %}</strong>
</div>
<div class="col-md-3 col-xs-6 col-md-offset-5 price">
<strong>{{ pending_sum|money:event.currency }}</strong>
<strong>{{ order.pending_sum|money:event.currency }}</strong>
</div>
<div class="clearfix"></div>
</div>
@@ -903,7 +903,7 @@
<tr>
<td colspan="1"></td>
<td colspan="5">
{{ p.html_info }}
{{ p.html_info|safe }}
{% if staff_session %}
<p>
<a href="" class="btn btn-default btn-xs admin-only" data-expandpayment data-id="{{ p.pk }}">
@@ -1018,7 +1018,7 @@
</dl>
{% endif %}
{% if r.html_info %}
{{ r.html_info }}
{{ r.html_info|safe }}
{% endif %}
{% if staff_session %}
<p>
@@ -2,7 +2,6 @@
{% load i18n %}
{% load static %}
{% load bootstrap3 %}
{% load escapejson %}
{% block inner %}
<h1>{% trans "Connect to device:" %} {{ device.name }}</h1>
@@ -19,7 +18,7 @@
{% trans "Open the app that you want to connect and optionally reset it to the original state." %}
</li>
<li>{% trans "Scan the following configuration code:" %}<br><br>
<script type="application/json" data-replace-with-qr>{{ qrdata|escapejson_dumps }}</script><br>
<script type="text/json" data-replace-with-qr>{{ qrdata|safe }}</script><br>
{% trans "If your app/device does not support scanning a QR code, you can also enter the following information:" %}
<br>
<strong>{% trans "System URL:" %}</strong> <code id="system_url">{{ settings.SITE_URL }}</code>
@@ -137,15 +137,6 @@
</td>
<td>
{{ d.software_brand|default_if_none:"" }} {{ d.software_version|default_if_none:"" }}
{% if staff_session %}
<details class="admin-only">
<summary>
<i class="fa fa-angle-down collapse-indicator"></i>
{% trans "Details" %}
</summary>
<pre class="admin-only">{{ d.info|pprint }}</pre>
</details>
{% endif %}
</td>
<td>
{% if d.initialized %}
@@ -4,7 +4,24 @@
{% block title %}{% trans "Organizer logs" %}{% endblock %}
{% block inside %}
<h1>{% trans "Organizer logs" %}</h1>
{% include "pretixcontrol/fragment_log_filter_form.html" %}
<form class="form-inline helper-display-inline" action="" method="get">
<input type="hidden" name="content_type" value="{{ request.GET.content_type }}">
<input type="hidden" name="object" value="{{ request.GET.object }}">
<p>
<select name="user" class="form-control">
<option value="">{% trans "All actions" %}</option>
{% for up in userlist %}
{% if up.user__id %}
<option value="{{ up.user__id }}"
{% if request.GET.user == up.user__id %}selected="selected"{% endif %}>
{{ up.user__email }}
</option>
{% endif %}
{% endfor %}
</select>
<button class="btn btn-primary" type="submit">{% trans "Filter" %}</button>
</p>
</form>
<ul class="list-group">
{% for log in logs %}
<li class="list-group-item logentry">
@@ -64,5 +81,5 @@
</div>
{% endfor %}
</ul>
{% include "pretixcontrol/pagination_huge.html" %}
{% include "pretixcontrol/pagination.html" %}
{% endblock %}
@@ -1,7 +1,6 @@
{% extends "pretixcontrol/base.html" %}
{% load i18n %}
{% load bootstrap3 %}
{% load escapejson %}
{% block title %}{% trans "Add a two-factor authentication device" %}{% endblock %}
{% block content %}
<h1>{% trans "Add a two-factor authentication device" %}</h1>
@@ -33,7 +32,7 @@
</li>
<li>
{% trans "Add a new account to the app by scanning the following barcode:" %}
<script type="application/json" data-replace-with-qr>{{ qrdata|escapejson_dumps }}</script>
<div class="qrcode-canvas" data-qrdata="#qrdata"></div>
<p>
<a data-toggle="collapse" href="#no_scan">
{% trans "Can't scan the barcode?" %}
@@ -82,4 +81,9 @@
</li>
</ol>
<script type="text/json" id="qrdata">
{{ qrdata|safe }}
</script>
{% endblock %}
@@ -3,7 +3,6 @@
{% load bootstrap3 %}
{% load static %}
{% load compress %}
{% load escapejson %}
{% block title %}{% trans "Add a two-factor authentication device" %}{% endblock %}
{% block content %}
<h1>{% trans "Add a two-factor authentication device" %}</h1>
@@ -27,7 +26,9 @@
{% trans "Device registration failed." %}
</div>
<script type="text/json" id="webauthn-enroll">
{{ jsondata|escapejson }}
{{ jsondata|safe }}
</script>
{% compress js %}
<script type="text/javascript" src="{% static "pretixcontrol/js/base64js.js" %}"></script>
@@ -3,7 +3,6 @@
{% load bootstrap3 %}
{% load compress %}
{% load static %}
{% load escapejson %}
{% block content %}
<form class="form-signin" id="webauthn-form" action="" method="post">
{% csrf_token %}
@@ -44,7 +43,7 @@
{% if jsondata %}
<script type="text/json" id="webauthn-login">
{{ jsondata|escapejson }}
{{ jsondata|safe }}
</script>
{% endif %}
{% compress js %}
@@ -115,34 +115,34 @@
{% endif %}
<th>
{% trans "Voucher code" %}
<a href="?{% url_replace request 'filter-ordering' '-code' %}"><i class="fa fa-caret-down"></i></a>
<a href="?{% url_replace request 'filter-ordering' 'code' %}"><i class="fa fa-caret-up"></i></a>
<a href="?{% url_replace request 'ordering' '-code' %}"><i class="fa fa-caret-down"></i></a>
<a href="?{% url_replace request 'ordering' 'code' %}"><i class="fa fa-caret-up"></i></a>
</th>
<th>
{% trans "Redemptions" %}
<a href="?{% url_replace request 'filter-ordering' '-redeemed' %}"><i class="fa fa-caret-down"></i></a>
<a href="?{% url_replace request 'filter-ordering' 'redeemed' %}"><i class="fa fa-caret-up"></i></a>
<a href="?{% url_replace request 'ordering' '-redeemed' %}"><i class="fa fa-caret-down"></i></a>
<a href="?{% url_replace request 'ordering' 'redeemed' %}"><i class="fa fa-caret-up"></i></a>
</th>
<th>
{% trans "Expiry" %}
<a href="?{% url_replace request 'filter-ordering' '-valid_until' %}"><i class="fa fa-caret-down"></i></a>
<a href="?{% url_replace request 'filter-ordering' 'valid_until' %}"><i class="fa fa-caret-up"></i></a>
<a href="?{% url_replace request 'ordering' '-valid_until' %}"><i class="fa fa-caret-down"></i></a>
<a href="?{% url_replace request 'ordering' 'valid_until' %}"><i class="fa fa-caret-up"></i></a>
</th>
<th>
{% trans "Tag" %}
<a href="?{% url_replace request 'filter-ordering' '-tag' %}"><i class="fa fa-caret-down"></i></a>
<a href="?{% url_replace request 'filter-ordering' 'tag' %}"><i class="fa fa-caret-up"></i></a>
<a href="?{% url_replace request 'ordering' '-tag' %}"><i class="fa fa-caret-down"></i></a>
<a href="?{% url_replace request 'ordering' 'tag' %}"><i class="fa fa-caret-up"></i></a>
</th>
<th>
{% trans "Product" %}
<a href="?{% url_replace request 'filter-ordering' '-item' %}"><i class="fa fa-caret-down"></i></a>
<a href="?{% url_replace request 'filter-ordering' 'item' %}"><i class="fa fa-caret-up"></i></a>
<a href="?{% url_replace request 'ordering' '-item' %}"><i class="fa fa-caret-down"></i></a>
<a href="?{% url_replace request 'ordering' 'item' %}"><i class="fa fa-caret-up"></i></a>
</th>
{% if request.event.has_subevents %}
<th>
{% trans "Date" context "subevent" %}
<a href="?{% url_replace request 'filter-ordering' '-subevent' %}"><i class="fa fa-caret-down"></i></a>
<a href="?{% url_replace request 'filter-ordering' 'subevent' %}"><i class="fa fa-caret-up"></i></a>
<a href="?{% url_replace request 'ordering' '-subevent' %}"><i class="fa fa-caret-down"></i></a>
<a href="?{% url_replace request 'ordering' 'subevent' %}"><i class="fa fa-caret-up"></i></a>
</th>
{% endif %}
<th></th>
@@ -251,7 +251,7 @@
</td>
<td>
{% if e.voucher %}
<a href="{% url "control:event.voucher" organizer=request.event.organizer.slug event=request.event.slug voucher=e.voucher.pk %}?next={{ request.get_full_path|urlencode }}">
<a href="{% url "control:event.voucher" organizer=request.event.organizer.slug event=request.event.slug voucher=e.voucher.pk %}">
{{ e.voucher }}
</a>
{% elif not e.voucher and e.availability.0 == 100 and e.availability.1|default_if_none:"none" != "none" %}
+1 -2
View File
@@ -273,8 +273,7 @@ urlpatterns = [
re_path(r'^$', dashboards.event_index, name='event.index'),
re_path(r'^qrcode.(?P<filetype>(png|jpeg|gif|svg))$', event.EventQRCode.as_view(), name='event.qrcode'),
re_path(r'^widgets.json$', dashboards.event_index_widgets_lazy, name='event.index.widgets'),
re_path(r'^dashboard/partials/logs$', dashboards.event_index_log_lazy, name='event.index.logs'),
re_path(r'^dashboard/partials/warnings$', dashboards.event_index_warnings_lazy, name='event.index.warnings'),
re_path(r'^logs/embed$', dashboards.event_index_log_lazy, name='event.index.logs'),
re_path(r'^live/$', event.EventLive.as_view(), name='event.live'),
re_path(r'^transfer_session/$', event.EventTransferSession.as_view(), name='event.transfer_session'),
re_path(r'^logs/$', event.EventLog.as_view(), name='event.log'),
+15 -6
View File
@@ -65,7 +65,6 @@ from pretix.base.forms.auth import (
from pretix.base.metrics import pretix_failed_logins, pretix_successful_logins
from pretix.base.models import TeamInvite, U2FDevice, User, WebAuthnDevice
from pretix.helpers.http import get_client_ip, redirect_to_url
from pretix.helpers.ratelimit import rate_limit, rate_limit_reset
from pretix.helpers.security import handle_login_source, session_login
logger = logging.getLogger(__name__)
@@ -320,12 +319,19 @@ class Forgot(TemplateView):
if self.form.is_valid():
email = self.form.cleaned_data['email']
has_redis = settings.HAS_REDIS
try:
user = User.objects.get(is_active=True, auth_backend='native', email__iexact=email)
if rate_limit("pwreset", user.pk, max_num=1, expire_time=3600 * 24):
user.log_action('pretix.control.auth.user.forgot_password.denied.repeated')
raise RepeatedResetDenied()
if has_redis:
from django_redis import get_redis_connection
rc = get_redis_connection("redis")
if rc.exists('pretix_pwreset_%s' % (user.id)):
user.log_action('pretix.control.auth.user.forgot_password.denied.repeated')
raise RepeatedResetDenied()
else:
rc.setex('pretix_pwreset_%s' % (user.id), 3600 * 24, '1')
except User.DoesNotExist:
logger.warning('Backend password reset for unregistered e-mail \"' + email + '\" requested.')
@@ -338,7 +344,6 @@ class Forgot(TemplateView):
user.log_action('pretix.control.auth.user.forgot_password.mail_sent')
finally:
has_redis = settings.HAS_REDIS
if has_redis:
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.'))
@@ -407,7 +412,11 @@ class Recover(TemplateView):
messages.success(request, _('You can now login using your new password.'))
user.log_action('pretix.control.auth.user.forgot_password.recovered')
rate_limit_reset("pwreset", user.pk)
has_redis = settings.HAS_REDIS
if has_redis:
from django_redis import get_redis_connection
rc = get_redis_connection("redis")
rc.delete('pretix_pwreset_%s' % user.id)
return redirect('control:auth.login')
else:
return self.get(request, *args, **kwargs)
+3 -10
View File
@@ -484,17 +484,10 @@ class CheckinListView(EventPermissionRequiredMixin, PaginationMixin, ListView):
def get_queryset(self):
qs = Checkin.all.filter(
list_id__in=self.request.event.checkin_lists.values_list('id', flat=True),
list__event=self.request.event,
).select_related(
'position', 'position__order', 'position__item', 'position__variation', 'position__subevent'
).prefetch_related(
# For events with huge numbers of check-ins, prefetch_related is a lot more efficient than
# select_related, since it just needs to query one page size of positions instead of joining
# multiple huge tables during result computation
Prefetch(
'position',
queryset=OrderPosition.all.select_related(
'order', 'item', 'variation', 'subevent',
)
),
'list', 'gate', 'device'
)
if self.filter_form.is_valid():
+49 -76
View File
@@ -49,7 +49,7 @@ from django.shortcuts import render
from django.template.loader import get_template
from django.urls import reverse
from django.utils.formats import date_format
from django.utils.html import conditional_escape, escape, format_html
from django.utils.html import escape
from django.utils.timezone import now
from django.utils.translation import gettext_lazy as _, ngettext, pgettext
@@ -112,7 +112,7 @@ def base_widgets(sender, subevent=None, lazy=False, **kwargs):
return [
{
'content': None if lazy else format_html(NUM_WIDGET, num=intcomma(tickc), text=_('Attendees (ordered)')),
'content': None if lazy else NUM_WIDGET.format(num=intcomma(tickc), text=_('Attendees (ordered)')),
'lazy': 'attendees-ordered',
'display_size': 'small',
'priority': 100,
@@ -122,7 +122,7 @@ def base_widgets(sender, subevent=None, lazy=False, **kwargs):
}) + ('?subevent={}'.format(subevent.pk) if subevent else '')
},
{
'content': None if lazy else format_html(NUM_WIDGET, num=intcomma(paidc), text=_('Attendees (paid)')),
'content': None if lazy else NUM_WIDGET.format(num=intcomma(paidc), text=_('Attendees (paid)')),
'lazy': 'attendees-paid',
'display_size': 'small',
'priority': 100,
@@ -132,8 +132,7 @@ def base_widgets(sender, subevent=None, lazy=False, **kwargs):
}) + ('?subevent={}'.format(subevent.pk) if subevent else '')
},
{
'content': None if lazy else format_html(
NUM_WIDGET,
'content': None if lazy else NUM_WIDGET.format(
num=money_filter(round_decimal(rev, sender.currency), sender.currency, hide_currency=True),
text=_('Total revenue ({currency})').format(currency=sender.currency)
),
@@ -146,7 +145,7 @@ def base_widgets(sender, subevent=None, lazy=False, **kwargs):
}) + ('?subevent={}'.format(subevent.pk) if subevent else '')
},
{
'content': None if lazy else format_html(NUM_WIDGET, num=prodc, text=_('Active products')),
'content': None if lazy else NUM_WIDGET.format(num=prodc, text=_('Active products')),
'lazy': 'active-products',
'display_size': 'small',
'priority': 100,
@@ -210,8 +209,8 @@ def waitinglist_widgets(sender, subevent=None, lazy=False, **kwargs):
quota_cache[q.pk] = (quota_cache[q.pk][0], quota_cache[q.pk][1] - min(wlt['cnt'], row[1]))
widgets.append({
'content': None if lazy else format_html(
NUM_WIDGET, num=intcomma(happy), text=_('available to give to people on waiting list')
'content': None if lazy else NUM_WIDGET.format(
num=intcomma(happy), text=_('available to give to people on waiting list')
),
'lazy': 'waitinglist-avail',
'priority': 50,
@@ -221,9 +220,7 @@ def waitinglist_widgets(sender, subevent=None, lazy=False, **kwargs):
})
})
widgets.append({
'content': None if lazy else format_html(
NUM_WIDGET, num=intcomma(wles.count()), text=_('total waiting list length')
),
'content': None if lazy else NUM_WIDGET.format(num=intcomma(wles.count()), text=_('total waiting list length')),
'lazy': 'waitinglist-length',
'display_size': 'small',
'priority': 50,
@@ -250,10 +247,9 @@ def quota_widgets(sender, subevent=None, lazy=False, **kwargs):
if not lazy:
status, left = qa.results[q] if q in qa.results else q.availability(allow_cache=True)
widgets.append({
'content': None if lazy else format_html(
NUM_WIDGET,
'content': None if lazy else NUM_WIDGET.format(
num='{}/{}'.format(intcomma(left), intcomma(q.size)) if q.size is not None else '\u221e',
text=format_html(_('{quota} left'), quota=q.name)
text=_('{quota} left').format(quota=escape(q.name))
),
'lazy': 'quota-{}'.format(q.pk),
'display_size': 'small',
@@ -272,8 +268,7 @@ def shop_state_widget(sender, **kwargs):
return [{
'display_size': 'small',
'priority': 1000,
'content': format_html(
'<div class="shopstate">{t1}<br><span class="{cls}"><span class="fa {icon}"></span> {state}</span>{t2}</div>',
'content': '<div class="shopstate">{t1}<br><span class="{cls}"><span class="fa {icon}"></span> {state}</span>{t2}</div>'.format(
t1=_('Your ticket shop is'), t2=_('Click here to change'),
state=_('live') if sender.live and not sender.testmode else (
_('live and in test mode') if sender.live else (
@@ -304,10 +299,9 @@ def checkin_widget(sender, subevent=None, lazy=False, **kwargs):
qs = sender.checkin_lists.filter(subevent=subevent)
for cl in qs:
widgets.append({
'content': None if lazy else format_html(
NUM_WIDGET,
'content': None if lazy else NUM_WIDGET.format(
num='{}/{}'.format(intcomma(cl.inside_count), intcomma(cl.position_count)),
text=format_html(_('Present {list}'), list=cl.name)
text=_('Present {list}').format(list=escape(cl.name))
),
'lazy': 'checkin-{}'.format(cl.pk),
'display_size': 'small',
@@ -346,12 +340,6 @@ def welcome_wizard_widget(sender, **kwargs):
}]
def build_json_response(widgets):
for widget in widgets:
widget['content'] = conditional_escape(widget['content'])
return JsonResponse({'widgets': widgets})
def event_index(request, organizer, event):
from pretix.control.forms.event import CommentForm
@@ -379,42 +367,6 @@ def event_index(request, organizer, event):
'comment_form': CommentForm(initial={'comment': request.event.comment}, readonly=not can_change_event_settings),
}
ctx['timeline'] = [
{
'date': t.datetime.astimezone(request.event.timezone).date(),
'entry': t,
'time': t.datetime.astimezone(request.event.timezone)
}
for t in timeline_for_event(request.event, subevent)
]
ctx['today'] = now().astimezone(request.event.timezone).date()
ctx['nearly_now'] = now().astimezone(request.event.timezone) - timedelta(seconds=20)
resp = render(request, 'pretixcontrol/event/index.html', ctx)
return resp
def event_index_widgets_lazy(request, organizer, event):
subevent = None
if request.GET.get("subevent", "") != "" and request.event.has_subevents:
i = request.GET.get("subevent", "")
try:
subevent = request.event.subevents.get(pk=i)
except SubEvent.DoesNotExist:
pass
widgets = []
for r, result in event_dashboard_widgets.send(sender=request.event, subevent=subevent, lazy=False):
widgets.extend(result)
return build_json_response(widgets)
def event_index_warnings_lazy(request, organizer, event):
can_view_orders = request.user.has_event_permission(request.organizer, request.event, 'event.orders:read',
request=request)
can_change_event_settings = request.user.has_event_permission(request.organizer, request.event,
'event.settings.general:write', request=request)
ctx = {}
ctx['has_overpaid_orders'] = can_view_orders and Order.annotate_overpayments(request.event.orders).filter(
Q(~Q(status=Order.STATUS_CANCELED) & Q(pending_sum_t__lt=0))
| Q(Q(status=Order.STATUS_CANCELED) & Q(pending_sum_rc__lt=0))
@@ -438,11 +390,35 @@ def event_index_warnings_lazy(request, organizer, event):
| Q(failed_attempts__gt=0)
).exists()
return render(
request,
'pretixcontrol/event/dashboard_partial_warnings.html',
ctx
)
ctx['timeline'] = [
{
'date': t.datetime.astimezone(request.event.timezone).date(),
'entry': t,
'time': t.datetime.astimezone(request.event.timezone)
}
for t in timeline_for_event(request.event, subevent)
]
ctx['today'] = now().astimezone(request.event.timezone).date()
ctx['nearly_now'] = now().astimezone(request.event.timezone) - timedelta(seconds=20)
resp = render(request, 'pretixcontrol/event/index.html', ctx)
# resp['Content-Security-Policy'] = "style-src 'unsafe-inline'"
return resp
def event_index_widgets_lazy(request, organizer, event):
subevent = None
if request.GET.get("subevent", "") != "" and request.event.has_subevents:
i = request.GET.get("subevent", "")
try:
subevent = request.event.subevents.get(pk=i)
except SubEvent.DoesNotExist:
pass
widgets = []
for r, result in event_dashboard_widgets.send(sender=request.event, subevent=subevent, lazy=False):
widgets.extend(result)
return JsonResponse({'widgets': widgets})
def event_index_log_lazy(request, organizer, event):
@@ -477,7 +453,7 @@ def event_index_log_lazy(request, organizer, event):
return render(
request,
'pretixcontrol/event/dashboard_partial_logs.html',
'pretixcontrol/event/logs_embed.html',
{
'logs': qs[:5]
}
@@ -529,7 +505,7 @@ def widgets_for_event_qs(request, qs, user, nmax, lazy=False):
<a href="{url}" class="event">
<div class="name">{event}</div>
<div class="daterange">{daterange}</div>
<div class="times">{times}{timezone}</div>
<div class="times">{times}</div>
</a>
<div class="bottomrow">
{orders}
@@ -573,16 +549,14 @@ def widgets_for_event_qs(request, qs, user, nmax, lazy=False):
status = ('success', _('On sale'))
widgets.append({
'content': format_html(
tpl,
'content': tpl.format(
event=escape(event.name),
times=_('Event series') if event.has_subevents else (
((date_format(event.date_admission.astimezone(tz), 'TIME_FORMAT') + ' / ')
if event.date_admission and event.date_admission != event.date_from else '')
+ (date_format(event.date_from.astimezone(tz), 'TIME_FORMAT') if event.date_from else '')
),
timezone=(
format_html(' <span class="fa fa-globe text-muted" data-toggle="tooltip" title="{}"></span>', tzname)
) + (
' <span class="fa fa-globe text-muted" data-toggle="tooltip" title="{}"></span>'.format(tzname)
if tzname != request.timezone and not event.has_subevents else ''
),
url=reverse('control:event.index', kwargs={
@@ -590,8 +564,7 @@ def widgets_for_event_qs(request, qs, user, nmax, lazy=False):
'organizer': event.organizer.slug
}),
orders=(
format_html(
'<a href="{orders_url}" class="orders">{orders_text}</a>',
'<a href="{orders_url}" class="orders">{orders_text}</a>'.format(
orders_url=reverse('control:event.orders', kwargs={
'event': event.slug,
'organizer': event.organizer.slug
@@ -658,7 +631,7 @@ def user_index_widgets_lazy(request):
request.user,
8
)
return build_json_response(widgets)
return JsonResponse({'widgets': widgets})
def user_index(request):
+30 -30
View File
@@ -41,7 +41,7 @@ from collections import OrderedDict, defaultdict
from decimal import Decimal
from io import BytesIO
from itertools import groupby
from urllib.parse import quote, urlsplit
from urllib.parse import urlsplit
from zoneinfo import ZoneInfo
import bleach
@@ -60,7 +60,7 @@ from django.http import (
Http404, HttpResponse, HttpResponseBadRequest, HttpResponseNotAllowed,
JsonResponse,
)
from django.shortcuts import redirect
from django.shortcuts import get_object_or_404, redirect
from django.urls import NoReverseMatch, reverse
from django.utils.functional import cached_property
from django.utils.html import conditional_escape, format_html
@@ -82,7 +82,7 @@ from pretix.base.models import Event, LogEntry, Order, TaxRule, Voucher
from pretix.base.models.event import EventMetaValue
from pretix.base.services import tickets
from pretix.base.services.invoices import build_preview_invoice_pdf
from pretix.base.signals import get_defining_app, register_ticket_outputs
from pretix.base.signals import register_ticket_outputs
from pretix.base.templatetags.rich_text import markdown_compile_email
from pretix.control.forms.event import (
CancelSettingsForm, CommentForm, ConfirmTextFormset, EventDeleteForm,
@@ -119,9 +119,8 @@ from ...helpers.compat import CompatDeleteView
from ...helpers.format import (
PlainHtmlAlternativeString, SafeFormatter, format_map,
)
from ..forms.filter import LogFilterForm
from ..logdisplay import OVERVIEW_BANLIST
from . import CreateView, LargeResultSetPaginator, PaginationMixin, UpdateView
from . import CreateView, PaginationMixin, UpdateView
logger = logging.getLogger(__name__)
@@ -442,7 +441,6 @@ class EventPlugins(EventSettingsViewMixin, EventPermissionRequiredMixin, Templat
plugins_available = {
p.module: p for p in self.available_plugins(self.object)
}
plugin_enabled = None
with transaction.atomic():
save_organizer = False
@@ -492,7 +490,6 @@ class EventPlugins(EventSettingsViewMixin, EventPermissionRequiredMixin, Templat
format_html(_('The plugin {} is now active.'),
format_html("<strong>{}</strong>", pluginmeta.name)),
]
plugin_enabled = module
messages.success(self.request, mark_safe("".join(info)))
else:
self.request.event.log_action('pretix.event.plugins.disabled', user=self.request.user,
@@ -502,19 +499,13 @@ class EventPlugins(EventSettingsViewMixin, EventPermissionRequiredMixin, Templat
self.object.save()
if save_organizer:
self.object.organizer.save()
return redirect(self.get_success_url(plugin_enabled))
return redirect(self.get_success_url())
def get_success_url(self, plugin_enabled) -> str:
if plugin_enabled and self.request.POST.get('go') == 'payment':
return reverse('control:event.settings.payment', kwargs={
'organizer': self.request.organizer.slug,
'event': self.request.event.slug,
}) + '?highlight=' + quote(plugin_enabled) + '#'
else:
return reverse('control:event.settings.plugins', kwargs={
'organizer': self.request.organizer.slug,
'event': self.request.event.slug,
})
def get_success_url(self) -> str:
return reverse('control:event.settings.plugins', kwargs={
'organizer': self.request.organizer.slug,
'event': self.request.event.slug,
})
class PaymentProviderSettings(EventSettingsViewMixin, EventPermissionRequiredMixin, TemplateView, SingleObjectMixin):
@@ -680,8 +671,6 @@ class PaymentSettings(WritePermissionMixin, EventSettingsViewMixin, EventSetting
p.sales_channels = [sales_channels[channel] for channel in p.settings.get('_restrict_to_sales_channels', as_type=list, default=['web'])]
if p.is_meta:
p.show_enabled = p.settings._enabled in (True, 'True')
if self.request.GET.get('highlight') and getattr(get_defining_app(p), 'name', None) == self.request.GET.get('highlight'):
p.highlight = True
return context
@@ -1254,7 +1243,6 @@ class EventDelete(RecentAuthenticationRequiredMixin, EventPermissionRequiredMixi
class EventLog(EventPermissionRequiredMixin, PaginationMixin, ListView):
template_name = 'pretixcontrol/event/logs.html'
model = LogEntry
paginator_class = LargeResultSetPaginator
context_object_name = 'logs'
def get_queryset(self):
@@ -1284,20 +1272,32 @@ class EventLog(EventPermissionRequiredMixin, PaginationMixin, ListView):
]
qs = qs.filter(content_type__in=allowed_types)
if self.filter_form.is_valid():
qs = self.filter_form.filter_qs(qs)
if self.request.GET.get('user') == 'yes':
qs = qs.filter(user__isnull=False)
elif self.request.GET.get('user') == 'no':
qs = qs.filter(user__isnull=True)
elif self.request.GET.get('user', '').startswith('d-'):
qs = qs.filter(device_id=self.request.GET.get('user')[2:])
elif self.request.GET.get('user'):
qs = qs.filter(user_id=self.request.GET.get('user'))
if self.request.GET.get('action_type'):
qs = qs.filter(action_type=self.request.GET['action_type'])
if self.request.GET.get('content_type'):
qs = qs.filter(content_type=get_object_or_404(ContentType, pk=self.request.GET.get('content_type')))
if self.request.GET.get('object'):
qs = qs.filter(object_id=self.request.GET.get('object'))
return qs
def get_context_data(self, **kwargs):
ctx = super().get_context_data()
ctx['filter_form'] = self.filter_form
ctx['userlist'] = self.request.event.logentry_set.order_by().distinct().values('user__id', 'user__email')
ctx['devicelist'] = self.request.event.logentry_set.order_by('device__name').distinct().values('device__id', 'device__name')
return ctx
@cached_property
def filter_form(self):
return LogFilterForm(data=self.request.GET, organizer=self.request.organizer)
class EventComment(EventPermissionRequiredMixin, View):
permission = 'event.settings.general:write'
@@ -1568,7 +1568,7 @@ class WidgetSettings(EventSettingsViewMixin, EventPermissionRequiredMixin, FormV
return ctx
class QuickSetupView(EventPermissionRequiredMixin, FormView):
class QuickSetupView(FormView):
template_name = 'pretixcontrol/event/quick_setup.html'
permission = 'event.settings.general:write'
form_class = QuickSetupForm
+9 -3
View File
@@ -35,7 +35,7 @@ from django.utils.translation import ngettext
from django.views import View
from django.views.generic import DetailView, ListView
from pretix.base.middleware import add_to_response_csp
from pretix.base.middleware import _merge_csp, _parse_csp, _render_csp
from pretix.base.models import OutgoingMail
from pretix.base.services.mail import mail_send_task
from pretix.control.forms.filter import OutgoingMailFilterForm
@@ -108,12 +108,18 @@ class OutgoingMailDetailView(OrganizerDetailViewMixin, OrganizerPermissionRequir
def dispatch(self, request, *args, **kwargs):
response = super().dispatch(request, *args, **kwargs)
add_to_response_csp(response, {
if 'Content-Security-Policy' in response:
h = _parse_csp(response['Content-Security-Policy'])
else:
h = {}
csps = {
'frame-src': ['data:'],
# Unfortuantely, we can't avoid unsafe-inline for style here.
# See outgoingmail.js for the protection measures we take.
'style-src': ["'unsafe-inline'"],
})
}
_merge_csp(h, csps)
response['Content-Security-Policy'] = _render_csp(h)
return response
def get_context_data(self, **kwargs):
+4 -75
View File
@@ -41,30 +41,6 @@ from pretix.control.forms.mailsetup import SimpleMailForm, SMTPMailForm
logger = logging.getLogger(__name__)
def get_cname_record(hostname):
try:
r = dns.resolver.Resolver()
answers = r.resolve(hostname, 'CNAME')
answers = list(answers)
if len(answers) != 1:
logger.exception('Found multiple CNAME records for {}'.format(hostname))
return
return str(answers[0].target).lower()
except:
logger.exception('Could not fetch CNAME record for {}'.format(hostname))
def get_dmarc_record(hostname):
try:
r = dns.resolver.Resolver()
for resp in r.resolve("_dmarc." + hostname, 'TXT'):
data = b''.join(resp.strings).decode()
if 'DMARC1' in data.strip():
return data
except:
logger.exception("Could not fetch DMARC record for {}".format(hostname))
def get_spf_record(hostname):
try:
r = dns.resolver.Resolver()
@@ -73,7 +49,7 @@ def get_spf_record(hostname):
if data.lower().strip().startswith('v=spf1 '): # RFC7208, section 4.5
return data
except:
logger.exception("Could not fetch SPF record for {}".format(hostname))
logger.exception("Could not fetch SPF record")
def _check_spf_record(not_found_lookup_parts, spf_record, depth):
@@ -192,15 +168,10 @@ class MailSettingsSetupView(TemplateView):
return super().get(request, *args, **kwargs)
session_key = f'sender_mail_verification_code_{self.request.path}_{self.simple_form.cleaned_data.get("mail_from")}'
verify_dns = (
settings.MAIL_CUSTOM_SENDER_SPF_STRING or
(settings.MAIL_CUSTOM_SENDER_DKIM_CNAME and settings.MAIL_CUSTOM_SENDER_DKIM_SELECTOR) or
settings.MAIL_CUSTOM_SENDER_DMARC_REQUIRED
)
allow_save = (
(not settings.MAIL_CUSTOM_SENDER_VERIFICATION_REQUIRED or
('verification' in self.request.POST and self.request.POST.get('verification', '') == self.request.session.get(session_key, None))) and
(not verify_dns or self.request.POST.get('state') == 'save')
(not settings.MAIL_CUSTOM_SENDER_SPF_STRING or self.request.POST.get('state') == 'save')
)
if allow_save:
@@ -221,8 +192,8 @@ class MailSettingsSetupView(TemplateView):
spf_warning = None
spf_record = None
hostname = self.simple_form.cleaned_data['mail_from'].split('@')[-1]
if settings.MAIL_CUSTOM_SENDER_SPF_STRING:
hostname = self.simple_form.cleaned_data['mail_from'].split('@')[-1]
spf_record = get_spf_record(hostname)
if not spf_record:
spf_warning = _(
@@ -239,43 +210,7 @@ class MailSettingsSetupView(TemplateView):
'this system in the SPF record.'
)
dkim_warning = None
dkim_hostname = None
dkim_cname = None
if settings.MAIL_CUSTOM_SENDER_DKIM_CNAME and settings.MAIL_CUSTOM_SENDER_DKIM_SELECTOR:
dkim_hostname = settings.MAIL_CUSTOM_SENDER_DKIM_SELECTOR + '._domainkey.' + hostname
cname_target = get_cname_record(dkim_hostname)
dkim_cname = settings.MAIL_CUSTOM_SENDER_DKIM_CNAME
if not dkim_cname.endswith("."):
dkim_cname += "."
if "%s" in dkim_cname:
dkim_cname = dkim_cname.replace("%s", hostname.replace(".", "-").lower())
if not cname_target:
dkim_warning = _(
'We could not find a CNAME record pointing to our DKIM key for domain you are trying to use. '
'This means that there is a very high change most of the emails will be rejected or marked as '
'spam. We strongly recommend setting up DKIM through a CNAME record. You can do so through the '
'DNS settings at the provider you registered your domain with.'
)
elif cname_target != dkim_cname:
dkim_warning = _(
'We found a CNAME record for a DKIM key, but it is not pointing to the right location. '
'This means that there is a very high chance most of the emails will be rejected or marked as '
'spam. You should update the DNS settings of your domain.'
)
dmarc_warning = None
dmarc_record = None
if settings.MAIL_CUSTOM_SENDER_DMARC_REQUIRED:
dmarc_record = get_dmarc_record(hostname)
if not dmarc_record:
spf_warning = _(
'We did not find DMARC record for your domain. This means that there is a very high chance '
'most of the emails will be rejected or marked as spam. You should update the DNS settings '
'of your domain.'
)
verification = settings.MAIL_CUSTOM_SENDER_VERIFICATION_REQUIRED and not spf_warning and not dkim_warning and not dmarc_warning
verification = settings.MAIL_CUSTOM_SENDER_VERIFICATION_REQUIRED and not spf_warning
if verification:
if 'verification' in self.request.POST:
messages.error(request, _('The verification code was incorrect, please try again.'))
@@ -306,12 +241,6 @@ class MailSettingsSetupView(TemplateView):
'spf_warning': spf_warning,
'spf_record': spf_record,
'spf_key': settings.MAIL_CUSTOM_SENDER_SPF_STRING,
'dkim_warning': dkim_warning,
'dkim_hostname': dkim_hostname,
'dkim_cname': dkim_cname,
'dmarc_warning': dmarc_warning,
'dmarc_record': dmarc_record,
'hostname': hostname,
'recp': self.simple_form.cleaned_data.get('mail_from')
},
using=self.template_engine,
+15 -40
View File
@@ -64,7 +64,7 @@ from django.urls import reverse
from django.utils import formats
from django.utils.formats import date_format, get_format
from django.utils.functional import cached_property
from django.utils.html import conditional_escape, escape, format_html
from django.utils.html import conditional_escape, escape
from django.utils.http import url_has_allowed_host_and_scheme
from django.utils.safestring import mark_safe
from django.utils.timezone import make_aware, now
@@ -79,9 +79,9 @@ from pretix.base.email import get_email_context
from pretix.base.exporter import MultiSheetListExporter
from pretix.base.i18n import language
from pretix.base.models import (
CachedFile, CachedTicket, Checkin, GiftCard, Invoice, InvoiceAddress, Item,
CachedFile, CachedTicket, Checkin, Invoice, InvoiceAddress, Item,
ItemVariation, LogEntry, Order, QuestionAnswer, Quota,
ScheduledEventExport, SeatCategoryMapping, generate_secret,
ScheduledEventExport, generate_secret,
)
from pretix.base.models.orders import (
CancellationRequest, OrderFee, OrderPayment, OrderPosition, OrderRefund,
@@ -551,10 +551,10 @@ class OrderDetail(OrderView):
ctx['refunds'] = self.order.refunds.select_related('payment').order_by('-created')
for p in ctx['payments']:
if p.payment_provider:
p.html_info = p.payment_provider.payment_control_render(self.request, p) or ""
p.html_info = (p.payment_provider.payment_control_render(self.request, p) or "").strip()
for r in ctx['refunds']:
if r.payment_provider:
r.html_info = r.payment_provider.refund_control_render(self.request, r) or ""
r.html_info = (r.payment_provider.refund_control_render(self.request, r) or "").strip()
ctx['invoices'] = list(self.order.invoices.all().select_related('event'))
ctx['comment_form'] = CommentForm(initial={
'comment': self.order.comment,
@@ -564,11 +564,10 @@ class OrderDetail(OrderView):
})
ctx['display_locale'] = dict(settings.LANGUAGES)[self.object.locale or self.request.event.settings.locale]
pending_sum = self.order.pending_sum
ctx['overpaid'] = pending_sum * -1
ctx['overpaid'] = self.order.pending_sum * -1
ctx['download_buttons'] = self.download_buttons
ctx['payment_refund_sum'] = self.order.payment_refund_sum
ctx['pending_sum'] = pending_sum
ctx['pending_sum'] = self.order.pending_sum
ctx['uncancelled_invoice'] = self.order.invoices.exclude(
Exists(self.order.invoices.filter(refers=OuterRef('pk'), is_cancellation=True))
).exclude(is_cancellation=True).first()
@@ -602,9 +601,8 @@ class OrderDetail(OrderView):
).prefetch_related(
'item__questions', 'issued_gift_cards', 'owned_gift_cards', 'linked_media',
Prefetch('answers', queryset=QuestionAnswer.objects.prefetch_related('options').select_related('question')),
Prefetch('all_checkins', queryset=Checkin.all.select_related('list', 'gate').order_by('datetime')),
Prefetch('all_checkins', queryset=Checkin.all.select_related('list').order_by('datetime')),
Prefetch('print_logs', queryset=PrintLog.objects.select_related('device').order_by('datetime')),
Prefetch('subevent', queryset=self.request.event.subevents.all()),
).order_by('positionid')
positions = []
@@ -1987,37 +1985,20 @@ class OrderChange(OrderView):
def fees(self):
fees = list(self.order.fees.all())
for f in fees:
f.form = OrderFeeChangeForm(
prefix='of-{}'.format(f.pk),
instance=f,
data=self.request.POST if self.request.method == "POST" else None
)
f.form = OrderFeeChangeForm(prefix='of-{}'.format(f.pk), instance=f,
data=self.request.POST if self.request.method == "POST" else None)
return fees
@cached_property
def positions(self):
positions = list(self.order.positions.select_related(
'item', 'item__tax_rule', 'used_membership', 'used_membership__membership_type', 'tax_rule',
'seat',
).prefetch_related(
Prefetch(
'subevent',
queryset=self.request.event.subevents.all(),
),
'granted_memberships',
'issued_gift_cards',
'addons',
).annotate(
_seat_allowed=Exists(SeatCategoryMapping.objects.filter(subevent=OuterRef("subevent"), product=OuterRef("item")))
))
'seat', 'subevent',
).prefetch_related('granted_memberships'))
for p in positions:
p.form = OrderPositionChangeForm(
prefix='op-{}'.format(p.pk),
instance=p,
items=self.items,
initial={'seat': p.seat.seat_guid if p.seat else None},
data=self.request.POST if self.request.method == "POST" else None
)
p.form = OrderPositionChangeForm(prefix='op-{}'.format(p.pk), instance=p, items=self.items,
initial={'seat': p.seat.seat_guid if p.seat else None},
data=self.request.POST if self.request.method == "POST" else None)
return positions
def get_context_data(self, **kwargs):
@@ -2280,12 +2261,6 @@ class OrderContactChange(OrderView):
def get_context_data(self, **kwargs):
ctx = super().get_context_data()
ctx['form'] = self.form
if self.order.all_positions.filter(Exists(GiftCard.objects.filter(issued_in=OuterRef('pk')))).exists():
self.form.fields['regenerate_secrets'].help_text = format_html(
'{}<br><br><strong><span class="fa fa-warning"></span> {}</strong>',
self.form.fields['regenerate_secrets'].help_text,
_("Ticket secrets of order positions that have been used to issue a gift card can not be changed. Only the link will be changed in this case."),
)
return ctx
@cached_property
+6 -13
View File
@@ -113,8 +113,7 @@ from pretix.base.views.tasks import AsyncAction
from pretix.control.forms.exports import ScheduledOrganizerExportForm
from pretix.control.forms.filter import (
CustomerFilterForm, DeviceFilterForm, EventFilterForm, GiftCardFilterForm,
LogFilterForm, OrganizerFilterForm, ReusableMediaFilterForm,
TeamFilterForm,
OrganizerFilterForm, ReusableMediaFilterForm, TeamFilterForm,
)
from pretix.control.forms.orders import ExporterForm
from pretix.control.forms.organizer import (
@@ -134,7 +133,7 @@ from pretix.control.permissions import (
organizer_permission_required,
)
from pretix.control.signals import nav_organizer
from pretix.control.views import LargeResultSetPaginator, PaginationMixin
from pretix.control.views import PaginationMixin
from pretix.control.views.mailsetup import MailSettingsSetupView
from pretix.helpers import OF_SELF, GroupConcat
from pretix.helpers.compat import CompatDeleteView
@@ -2664,7 +2663,6 @@ class LogView(OrganizerPermissionRequiredMixin, PaginationMixin, ListView):
template_name = 'pretixcontrol/organizers/logs.html'
permission = 'organizer.settings.general:write'
model = LogEntry
paginator_class = LargeResultSetPaginator
context_object_name = 'logs'
def get_queryset(self):
@@ -2674,21 +2672,16 @@ class LogView(OrganizerPermissionRequiredMixin, PaginationMixin, ListView):
'user', 'content_type', 'api_token', 'oauth_application', 'device'
).order_by('-datetime')
qs = qs.exclude(action_type__in=OVERVIEW_BANLIST)
if self.filter_form.is_valid():
qs = self.filter_form.filter_qs(qs)
if self.request.GET.get('action_type'):
qs = qs.filter(action_type=self.request.GET['action_type'])
if self.request.GET.get('user'):
qs = qs.filter(user_id=self.request.GET.get('user'))
return qs
def get_context_data(self, **kwargs):
ctx = super().get_context_data()
ctx['filter_form'] = self.filter_form
return ctx
@cached_property
def filter_form(self):
return LogFilterForm(data=self.request.GET, organizer=self.request.organizer)
class MembershipTypeListView(OrganizerDetailViewMixin, OrganizerPermissionRequiredMixin, ListView):
model = MembershipType
+1 -2
View File
@@ -85,7 +85,6 @@ from pretix.control.views import PaginationMixin
from pretix.control.views.event import MetaDataEditorMixin
from pretix.helpers import GroupConcat
from pretix.helpers.compat import CompatDeleteView
from pretix.helpers.i18n import get_format_without_seconds
from pretix.helpers.models import modelcopy
@@ -879,7 +878,7 @@ class SubEventBulkCreate(SubEventEditorMixin, EventPermissionRequiredMixin, Asyn
ctx['rrule_formset'] = self.rrule_formset
ctx['time_formset'] = self.time_formset
tf = get_format_without_seconds('TIME_INPUT_FORMATS')
tf = get_format('TIME_INPUT_FORMATS')[0]
ctx['time_admission_sample'] = time(8, 30, 0).strftime(tf)
ctx['time_begin_sample'] = time(9, 0, 0).strftime(tf)
ctx['time_end_sample'] = time(18, 0, 0).strftime(tf)
-22
View File
@@ -46,7 +46,6 @@ from django.contrib.auth import update_session_auth_hash
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import BadRequest, PermissionDenied
from django.db import transaction
from django.http import HttpResponse
from django.shortcuts import get_object_or_404, redirect
from django.urls import reverse
from django.utils.crypto import get_random_string
@@ -81,7 +80,6 @@ from pretix.control.permissions import (
)
from pretix.control.views.auth import get_u2f_appid, get_webauthn_rp_id
from pretix.helpers.http import redirect_to_url
from pretix.helpers.ratelimit import rate_limit, rate_limit_reset
from pretix.helpers.security import session_reauth
from pretix.helpers.u2f import websafe_encode
@@ -96,20 +94,6 @@ class RecentAuthenticationRequiredMixin:
def dispatch(self, request, *args, **kwargs):
tdelta = time.time() - request.session.get('pretix_auth_login_time', 0)
if tdelta > self.max_time:
if request.headers.get("X-Requested-With") == "XMLHttpRequest":
# It's not useful to return a 302 redirect on a XMLHttpRequest request, because
# the XMLHttpRequest is unable to detect redirects.
return HttpResponse(
"Authentication required",
status=401,
headers={
# Appending ?next= is handled by client, because it should be the top-level context url,
# not the URL called in the background
"X-Login-Url": reverse('control:user.reauth')
}
)
return redirect(reverse('control:user.reauth') + '?next=' + quote(request.get_full_path()))
return super().dispatch(request, *args, **kwargs)
@@ -865,7 +849,6 @@ class UserPasswordChangeView(FormView):
msgs = []
msgs.append(_('Your password has been changed.'))
self.request.user.send_security_notice(msgs)
rate_limit_reset("pwreset", self.request.user.pk)
self.request.user.log_action('pretix.user.settings.changed', user=self.request.user, data={'new_pw': True})
@@ -896,7 +879,6 @@ class UserEmailChangeView(RecentAuthenticationRequiredMixin, FormView):
return {
**super().get_form_kwargs(),
"request": self.request,
"user": self.request.user,
}
@@ -926,10 +908,6 @@ class UserEmailVerifyView(View):
messages.success(self.request, _('Your email address was already verified.'))
return redirect(reverse('control:user.settings', kwargs={}))
if rate_limit("emailverify", self.request.user.pk, max_num=2, expire_time=300):
messages.error(self.request, _("For security reasons, please wait 5 minutes before you try again."))
return redirect(reverse('control:user.settings', kwargs={}))
self.request.user.send_confirmation_code(
session=self.request.session,
reason='email_verify',
-3
View File
@@ -53,7 +53,6 @@ from django.shortcuts import redirect, render
from django.urls import resolve, reverse
from django.utils.functional import cached_property
from django.utils.html import format_html
from django.utils.http import url_has_allowed_host_and_scheme
from django.utils.safestring import mark_safe
from django.utils.timezone import now
from django.utils.translation import gettext_lazy as _
@@ -351,8 +350,6 @@ class VoucherUpdate(EventPermissionRequiredMixin, UpdateView):
return super().post(request, *args, **kwargs)
def get_success_url(self) -> str:
if "next" in self.request.GET and url_has_allowed_host_and_scheme(self.request.GET.get("next"), allowed_hosts=None):
return self.request.GET.get("next")
return reverse('control:event.vouchers', kwargs={
'organizer': self.request.event.organizer.slug,
'event': self.request.event.slug,
-37
View File
@@ -19,9 +19,7 @@
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
# <https://www.gnu.org/licenses/>.
#
import itertools
import re
from http.cookies import Morsel
from django.conf import settings
@@ -50,41 +48,6 @@ def set_cookie_without_samesite(request, response, key, *args, **kwargs):
response.cookies[key]['Partitioned'] = True
def thoroughly_delete_cookie(response, cookie_name, **kwargs):
""" Deletes different possible versions of a cookie (SameSite, Partitioned) """
properties = {"SameSite": ["", 'None'], "Partitioned": ["", True]}
for i, values in enumerate(itertools.product(*properties.values())):
m = Morsel()
m.set(cookie_name, '', '')
m.update(kwargs)
m.update(zip(properties.keys(), values))
m['expires'] = "Thu, 01 Jan 1970 00:00:00 GMT"
response.cookies[f'___DELETECOOKIE__{i}___{cookie_name}'] = m
# Make sure settings a cookie afterwards will add a new item in the dictionary, placing
# it below our deletion headers.
response.cookies.pop(cookie_name, None)
def get_all_values_of_cookie(cookie_header, cookie_name):
# like django.http.cookie.parse_cookie, but returns all values of duplicated cookies instead of only the last
values = list()
if not cookie_header:
return values
for chunk in cookie_header.split(";"):
if "=" in chunk:
key, val = chunk.split("=", 1)
else:
# Assume an empty name per
# https://bugzilla.mozilla.org/show_bug.cgi?id=169091
key, val = "", chunk
key, val = key.strip(), val.strip()
if key == cookie_name:
values.append(val)
return values
# Based on https://www.chromium.org/updates/same-site/incompatible-clients
# Copyright 2019 Google LLC.
# SPDX-License-Identifier: Apache-2.0
+1 -1
View File
@@ -47,5 +47,5 @@ def escapejson(value):
@keep_lazy(str, SafeText)
def escapejson_attr(value):
"""Hex encodes characters for use in a html attribute."""
"""Hex encodes characters for use in a html attributw script."""
return mark_safe(force_str(value).translate(_json_escapes_attr))
-32
View File
@@ -20,11 +20,9 @@
# <https://www.gnu.org/licenses/>.
#
import copy
from decimal import Decimal
from django.core.files import File
from django.db import models
from django.db.models.fields import DecimalField
class Thumbnail(models.Model):
@@ -56,33 +54,3 @@ def flatten_choices(choices):
yield from label_or_nested
else:
yield value_or_group, label_or_nested
def _normalize_decimal(d: Decimal) -> Decimal:
"""
Strips trailing zeros, e.g.
20.000 20
20.010 20.01
20.100 20.1
But unlike of Decimal.normalize(), 20.000 will not become 2e+1. Very small decimals might still be represented
in scientific notation when printed.
"""
normalized = d.normalize()
sign, digit, exponent = normalized.as_tuple()
if exponent > 0:
return normalized.quantize(1)
return normalized
class NormalizedDecimalField(DecimalField):
"""
Variant of DecimalField that never outputs the trailing zeros, so we always have normalized decimals internally.
Use this only for fields where the trailing zeros are pointless (e.g. percentages), not for monetary amounts.
"""
def from_db_value(self, value, expression, connection):
if value is not None:
value = _normalize_decimal(value)
return value
+13 -4
View File
@@ -19,6 +19,7 @@
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
# <https://www.gnu.org/licenses/>.
#
import ipaddress
import socket
import sys
import types
@@ -41,7 +42,8 @@ from urllib3.util.connection import (
from urllib3.util.timeout import _DEFAULT_TIMEOUT
from pretix.helpers.reportlab import ThumbnailingImageReader
from pretix.helpers.ssrf import should_block_access
_cgnat_net = ipaddress.ip_network('100.64.0.0/10')
def monkeypatch_vobject_performance():
@@ -148,9 +150,16 @@ def monkeypatch_urllib3_ssrf_protection():
af, socktype, proto, canonname, sa = res
if not getattr(settings, "ALLOW_HTTP_TO_PRIVATE_NETWORKS", False):
is_private, msg = should_block_access(sa)
if is_private:
raise HTTPError(msg)
ip_addr = ipaddress.ip_address(sa[0])
check_ip4 = ip_addr.ipv4_mapped if getattr(ip_addr, "ipv4_mapped", None) else ip_addr
if ip_addr.is_multicast:
raise HTTPError(f"Request to multicast address {sa[0]} blocked")
if ip_addr.is_loopback or ip_addr.is_link_local:
raise HTTPError(f"Request to local address {sa[0]} blocked")
if ip_addr.is_private:
raise HTTPError(f"Request to private address {sa[0]} blocked")
if check_ip4 in _cgnat_net:
raise HTTPError(f"Request to RFC 6598 address {sa[0]} blocked")
sock = None
try:
-116
View File
@@ -1,116 +0,0 @@
#
# This file is part of pretix (Community Edition).
#
# Copyright (C) 2014-2020 Raphael Michel and contributors
# Copyright (C) 2020-today pretix GmbH and contributors
#
# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General
# Public License as published by the Free Software Foundation in version 3 of the License.
#
# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are
# applicable granting you additional permissions and placing additional restrictions on your usage of this software.
# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive
# this file, see <https://pretix.eu/about/en/license>.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
# <https://www.gnu.org/licenses/>.
#
import hashlib
import ipaddress
import logging
from django.conf import settings
from django.http import HttpRequest
from pretix.helpers.http import get_client_ip
logger = logging.getLogger(__name__)
def _get_key(key, parameters):
return f'pretix:ratelimit:{key}:' + hashlib.sha256(','.join(str(p) for p in parameters).encode()).hexdigest()
def _get_ip(request):
client_ip = get_client_ip(request)
if not client_ip:
return None
try:
client_ip = ipaddress.ip_address(client_ip)
except ValueError:
# Web server not set up correctly
return None
if client_ip.is_private and not settings.DEBUG:
# This is the private IP of the server, web server not set up correctly
return None
return str(client_ip)
def rate_limit(key: str, *parameters, include_ip_from_request: HttpRequest=None, max_num: int, expire_time: int, increase: bool = True):
"""
This is a shared utility to implement simple rate limiting in operations like
password resets.
:param key: The key referring to the feature like "pwreset"
:param parameters: Any number of things to be hashed as the bucket key
:param include_ip_from_request: Add IP address from request to the bucket key. If IP address cannot be determined,
rate limit is not applied.
:param max_num: The maximum number of actions to performed within expire_time of the first action
:param expire_time: The length of the time window in seconds
:param increase: Whether to count the call as an event counted towards the rate, or just check
:return:
"""
if not settings.HAS_REDIS:
# No rate limiting
return False
from django_redis import get_redis_connection
rc = get_redis_connection("redis")
if include_ip_from_request:
ip = _get_ip(include_ip_from_request)
if not ip:
# IP not discovered, can't rate limit
return False
parameters = (*parameters, ip)
redis_key = _get_key(key, parameters)
if increase:
p = rc.pipeline()
p.set(redis_key, 0, nx=True, ex=expire_time) # Start a rate limit window if none is running
p.incr(redis_key)
new_counter = p.execute()[1]
else:
new_counter = int(rc.get(redis_key) or 0)
if new_counter > max_num:
return True
return False
def rate_limit_reset(key: str, *parameters, include_ip_from_request: HttpRequest=None):
"""
Reset a rate limit bucket.
"""
if not settings.HAS_REDIS:
# No rate limiting
return
from django_redis import get_redis_connection
rc = get_redis_connection("redis")
if include_ip_from_request:
ip = _get_ip(include_ip_from_request)
if not ip:
# IP not discovered, can't rate limit
return False
parameters = (*parameters, ip)
redis_key = _get_key(key, parameters)
rc.delete(redis_key)
+3 -3
View File
@@ -28,7 +28,7 @@ from django.contrib.auth import login as auth_login
from django.contrib.gis import geoip2
from django.core.cache import cache
from django.utils.formats import date_format
from django.utils.timezone import localtime, now, override
from django.utils.timezone import now
from django.utils.translation import gettext_lazy as _
from django_countries.fields import Country
from geoip2.errors import AddressNotFoundError
@@ -167,13 +167,13 @@ def handle_login_source(user, request):
})
if user.known_login_sources.count() > 1:
# Do not send on first login or first login after introduction of this feature:
with language(user.locale), override(user.timezone):
with language(user.locale):
mail(
user.email,
_('New sign-in to your account'),
'pretixcontrol/email/login_notice.txt',
{
'when': date_format(localtime(src.last_seen), 'DATETIME_FORMAT'),
'when': date_format(src.last_seen, 'DATETIME_FORMAT'),
'agent': src.agent_type,
'os': src.os_type,
# ua-parser returns "Other" for unidentified desktop devices.
-40
View File
@@ -1,40 +0,0 @@
#
# This file is part of pretix (Community Edition).
#
# Copyright (C) 2014-2020 Raphael Michel and contributors
# Copyright (C) 2020-today pretix GmbH and contributors
#
# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General
# Public License as published by the Free Software Foundation in version 3 of the License.
#
# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are
# applicable granting you additional permissions and placing additional restrictions on your usage of this software.
# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive
# this file, see <https://pretix.eu/about/en/license>.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
# <https://www.gnu.org/licenses/>.
#
import ipaddress
_cgnat_net = ipaddress.ip_network('100.64.0.0/10')
def should_block_access(sa):
ip_addr = ipaddress.ip_address(sa[0])
check_ip4 = ip_addr.ipv4_mapped if getattr(ip_addr, "ipv4_mapped", None) else ip_addr
if ip_addr.is_multicast:
return True, f"Request to multicast address {sa[0]} blocked"
if ip_addr.is_loopback or ip_addr.is_link_local:
return True, f"Request to local address {sa[0]} blocked"
if ip_addr.is_private:
return True, f"Request to private address {sa[0]} blocked"
if check_ip4 in _cgnat_net:
return True, f"Request to RFC 6598 address {sa[0]} blocked"
return False, None
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+222 -367
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-30 13:52+0000\n"
"POT-Creation-Date: 2026-07-07 09:30+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
@@ -17,6 +17,38 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
#: htmlcov/d_daa1541d0cbf5e2b_dashboards_py.html
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/views/dashboards.py
msgid "Shop disabled"
msgstr ""
#: htmlcov/d_daa1541d0cbf5e2b_dashboards_py.html pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/subevents/detail.html
#: pretix/control/templates/pretixcontrol/subevents/index.html
msgid "Presale over"
msgstr ""
#: htmlcov/d_daa1541d0cbf5e2b_dashboards_py.html pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/subevents/detail.html
#: pretix/control/templates/pretixcontrol/subevents/index.html
msgid "Presale not started"
msgstr ""
#: htmlcov/d_daa1541d0cbf5e2b_dashboards_py.html
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/subevents/detail.html
#: pretix/control/templates/pretixcontrol/subevents/index.html
#: pretix/control/views/dashboards.py
msgid "On sale"
msgstr ""
#: pretix/_base_settings.py
msgid "English"
msgstr ""
@@ -1167,19 +1199,6 @@ msgstr ""
msgid "Download a spreadsheet of all currently registered customer accounts."
msgstr ""
#: pretix/base/exporters/customers.py pretix/base/permissions.py
#: pretix/control/navigation.py
#: pretix/control/templates/pretixcontrol/organizers/customers.html
msgid "Customers"
msgstr ""
#: pretix/base/exporters/customers.py pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/organizers/customer.html
#: pretix/presale/templates/pretixpresale/organizers/customer_memberships.html
#: pretix/presale/views/customer.py
msgid "Memberships"
msgstr ""
#: pretix/base/exporters/customers.py pretix/base/models/customers.py
#: pretix/control/templates/pretixcontrol/organizers/customer.html
#: pretix/control/templates/pretixcontrol/organizers/customers.html
@@ -1312,66 +1331,6 @@ msgstr ""
msgid "No"
msgstr ""
#: pretix/base/exporters/customers.py pretix/base/exporters/orderlist.py
#: pretix/base/models/memberships.py pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/event/live.html
msgid "Test mode"
msgstr ""
#: pretix/base/exporters/customers.py pretix/base/models/memberships.py
#: pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/orders/fragment_order_status.html
#: pretix/control/templates/pretixcontrol/orders/overview.html
#: pretix/control/templates/pretixcontrol/organizers/customer_membership.html
#: pretix/plugins/reports/exporters.py
#: pretix/presale/templates/pretixpresale/event/fragment_order_status.html
#: pretix/presale/templates/pretixpresale/organizers/customer_membership.html
#: pretix/presale/templates/pretixpresale/organizers/customer_memberships.html
msgid "Canceled"
msgstr ""
#: pretix/base/exporters/customers.py pretix/base/models/memberships.py
#: pretix/control/templates/pretixcontrol/organizers/customer.html
#: pretix/presale/templates/pretixpresale/organizers/customer_membership.html
msgid "Membership type"
msgstr ""
#: pretix/base/exporters/customers.py
msgid "Purchase ticket"
msgstr ""
#: pretix/base/exporters/customers.py pretix/base/exporters/orderlist.py
#: pretix/base/exporters/waitinglist.py pretix/base/forms/questions.py
#: pretix/base/models/memberships.py pretix/control/forms/rrule.py
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/order/index.html
#: pretix/control/templates/pretixcontrol/orders/refunds.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/search/payments.html
#: pretix/control/templates/pretixcontrol/user/staff_session_edit.html
#: pretix/control/templates/pretixcontrol/user/staff_session_list.html
#: pretix/plugins/checkinlists/exporters.py
msgid "Start date"
msgstr ""
#: pretix/base/exporters/customers.py
msgid "Start time"
msgstr ""
#: pretix/base/exporters/customers.py pretix/base/exporters/orderlist.py
#: pretix/base/exporters/waitinglist.py pretix/base/models/memberships.py
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/user/staff_session_edit.html
#: pretix/control/templates/pretixcontrol/user/staff_session_list.html
#: pretix/plugins/checkinlists/exporters.py
msgid "End date"
msgstr ""
#: pretix/base/exporters/customers.py
msgid "End time"
msgstr ""
#: pretix/base/exporters/dekodi.py pretix/base/exporters/invoices.py
msgctxt "export_category"
msgid "Invoices"
@@ -2199,6 +2158,30 @@ msgstr ""
msgid "Position ID"
msgstr ""
#: pretix/base/exporters/orderlist.py pretix/base/exporters/waitinglist.py
#: pretix/base/forms/questions.py pretix/base/models/memberships.py
#: pretix/control/forms/rrule.py
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/order/index.html
#: pretix/control/templates/pretixcontrol/orders/refunds.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/search/payments.html
#: pretix/control/templates/pretixcontrol/user/staff_session_edit.html
#: pretix/control/templates/pretixcontrol/user/staff_session_list.html
#: pretix/plugins/checkinlists/exporters.py
msgid "Start date"
msgstr ""
#: pretix/base/exporters/orderlist.py pretix/base/exporters/waitinglist.py
#: pretix/base/models/memberships.py
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/user/staff_session_edit.html
#: pretix/control/templates/pretixcontrol/user/staff_session_list.html
#: pretix/plugins/checkinlists/exporters.py
msgid "End date"
msgstr ""
#: pretix/base/exporters/orderlist.py pretix/base/exporters/waitinglist.py
#: pretix/base/modelimport_orders.py pretix/base/modelimport_vouchers.py
#: pretix/base/models/items.py pretix/base/models/vouchers.py
@@ -2590,6 +2573,12 @@ msgstr ""
msgid "Gift card code"
msgstr ""
#: pretix/base/exporters/orderlist.py pretix/base/models/memberships.py
#: pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/event/live.html
msgid "Test mode"
msgstr ""
#: pretix/base/exporters/orderlist.py pretix/base/models/organizer.py
#: pretix/control/forms/event.py pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/email_setup.html
@@ -2703,7 +2692,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/orders/overview.html
#: pretix/control/templates/pretixcontrol/organizers/customer.html
#: pretix/control/templates/pretixcontrol/organizers/giftcards.html
#: pretix/plugins/reports/exporters.py pretix/plugins/sendmail/forms.py
#: pretix/plugins/reports/exporters.py
#: pretix/presale/templates/pretixpresale/event/fragment_order_status.html
#: pretix/presale/templates/pretixpresale/organizers/customer_giftcards.html
msgid "Expired"
@@ -2869,7 +2858,7 @@ msgid "This combination of credentials is not known to our system."
msgstr ""
#: pretix/base/forms/auth.py pretix/base/forms/user.py
#: pretix/control/views/user.py pretix/presale/forms/customer.py
#: pretix/presale/forms/customer.py
msgid "For security reasons, please wait 5 minutes before you try again."
msgstr ""
@@ -3792,7 +3781,6 @@ msgstr ""
#: pretix/base/modelimport_vouchers.py pretix/base/models/vouchers.py
#: pretix/control/templates/pretixcontrol/vouchers/bulk.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk_edit.html
#: pretix/control/templates/pretixcontrol/vouchers/detail.html
#: pretix/control/views/vouchers.py
msgid "Price effect"
@@ -4410,8 +4398,8 @@ msgstr ""
#: pretix/base/models/event.py
msgid ""
"This will be used to let users know if the event is in a different timezone, "
"and to let us calculate the local time of a user."
"This will be used to let users know if the event is in a different timezone "
"and lets us calculate users local times."
msgstr ""
#: pretix/base/models/event.py pretix/base/models/organizer.py
@@ -5706,6 +5694,23 @@ msgstr ""
msgid "Number of times this membership can be used in a purchase."
msgstr ""
#: pretix/base/models/memberships.py pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/orders/fragment_order_status.html
#: pretix/control/templates/pretixcontrol/orders/overview.html
#: pretix/control/templates/pretixcontrol/organizers/customer_membership.html
#: pretix/plugins/reports/exporters.py
#: pretix/presale/templates/pretixpresale/event/fragment_order_status.html
#: pretix/presale/templates/pretixpresale/organizers/customer_membership.html
#: pretix/presale/templates/pretixpresale/organizers/customer_memberships.html
msgid "Canceled"
msgstr ""
#: pretix/base/models/memberships.py
#: pretix/control/templates/pretixcontrol/organizers/customer.html
#: pretix/presale/templates/pretixpresale/organizers/customer_membership.html
msgid "Membership type"
msgstr ""
#: pretix/base/models/orders.py
msgid "pending"
msgstr ""
@@ -6484,7 +6489,7 @@ msgstr ""
msgid "It is currently not possible to create vouchers for add-on products."
msgstr ""
#: pretix/base/models/vouchers.py pretix/control/forms/vouchers.py
#: pretix/base/models/vouchers.py
msgid ""
"You need to select a specific product or quota if this voucher should "
"reserve tickets."
@@ -6503,7 +6508,7 @@ msgid ""
"usages."
msgstr ""
#: pretix/base/models/vouchers.py pretix/control/forms/vouchers.py
#: pretix/base/models/vouchers.py
msgid ""
"If you want this voucher to block quota, you need to select a specific date."
msgstr ""
@@ -6972,12 +6977,6 @@ msgstr ""
msgid "This gift card was used in the meantime. Please try again."
msgstr ""
#: pretix/base/payment.py
msgid ""
"This payment provider exists for historical purposes only and is no longer "
"usable."
msgstr ""
#: pretix/base/pdf.py
msgid "Ticket code (barcode content)"
msgstr ""
@@ -7534,6 +7533,11 @@ msgid ""
"permissions."
msgstr ""
#: pretix/base/permissions.py pretix/control/navigation.py
#: pretix/control/templates/pretixcontrol/organizers/customers.html
msgid "Customers"
msgstr ""
#: pretix/base/permissions.py pretix/control/navigation.py
msgid "Devices"
msgstr ""
@@ -8659,12 +8663,6 @@ msgid ""
"card."
msgstr ""
#: pretix/base/services/orders.py
msgid ""
"You cannot change the ticket secret of a position that has been used to "
"issue a gift card."
msgstr ""
#: pretix/base/services/orders.py
#, python-brace-format
msgid ""
@@ -10197,11 +10195,11 @@ msgstr ""
msgid "We'll show this publicly to allow attendees to contact you."
msgstr ""
#: pretix/base/settings.py
#: pretix/base/settings.py pretix/control/forms/event.py
msgid "Contact URL"
msgstr ""
#: pretix/base/settings.py
#: pretix/base/settings.py pretix/control/forms/event.py
msgid ""
"If you set this, the footer contact link will point here instead of using "
"the email address above. Please note that you still need to add a contact "
@@ -11682,7 +11680,6 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/organizers/customer.html
#: pretix/control/templates/pretixcontrol/organizers/customer_membership.html
#: pretix/control/templates/pretixcontrol/organizers/customers.html
#: pretix/control/templates/pretixcontrol/organizers/devices.html
#: pretix/control/templates/pretixcontrol/organizers/giftcard.html
#: pretix/control/templates/pretixcontrol/organizers/giftcards.html
#: pretix/control/templates/pretixcontrol/organizers/reusable_media.html
@@ -12878,7 +12875,7 @@ msgstr ""
msgid "Valid orders"
msgstr ""
#: pretix/control/forms/filter.py pretix/plugins/sendmail/forms.py
#: pretix/control/forms/filter.py
msgid "Paid (or canceled with paid fee)"
msgstr ""
@@ -12902,7 +12899,7 @@ msgstr ""
msgid "Cancellations"
msgstr ""
#: pretix/control/forms/filter.py pretix/plugins/sendmail/forms.py
#: pretix/control/forms/filter.py
msgid "Canceled (fully)"
msgstr ""
@@ -13077,22 +13074,6 @@ msgstr ""
msgid "Inactive"
msgstr ""
#: pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/subevents/detail.html
#: pretix/control/templates/pretixcontrol/subevents/index.html
msgid "Presale not started"
msgstr ""
#: pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/subevents/detail.html
#: pretix/control/templates/pretixcontrol/subevents/index.html
msgid "Presale over"
msgstr ""
#: pretix/control/forms/filter.py
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/import_form.html
msgid "Date from"
@@ -13130,6 +13111,13 @@ msgstr ""
msgid "not yet activated"
msgstr ""
#: pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/organizers/customer.html
#: pretix/presale/templates/pretixpresale/organizers/customer_memberships.html
#: pretix/presale/views/customer.py
msgid "Memberships"
msgstr ""
#: pretix/control/forms/filter.py
msgid "Has no memberships"
msgstr ""
@@ -13357,36 +13345,6 @@ msgstr ""
msgid "Search email address or subject"
msgstr ""
#: pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/order/index.html
#: pretix/control/templates/pretixcontrol/orders/refunds.html
msgid "Source"
msgstr ""
#: pretix/control/forms/filter.py
msgid "All sources"
msgstr ""
#: pretix/control/forms/filter.py
msgid "Team actions"
msgstr ""
#: pretix/control/forms/filter.py
msgid "Customer actions"
msgstr ""
#: pretix/control/forms/filter.py
msgid "Device actions"
msgstr ""
#: pretix/control/forms/filter.py
msgid "User email"
msgstr ""
#: pretix/control/forms/filter.py pretix/control/navigation.py
msgid "All users"
msgstr ""
#: pretix/control/forms/global_settings.py
msgid "Additional footer text"
msgstr ""
@@ -14564,7 +14522,6 @@ msgstr ""
#: pretix/control/forms/renderers.py
#: pretix/control/templates/pretixcontrol/organizers/device_bulk_edit.html
#: pretix/control/templates/pretixcontrol/subevents/bulk_edit.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk_edit.html
msgctxt "form_bulk"
msgid "change"
msgstr ""
@@ -14678,53 +14635,6 @@ msgid ""
"should show them."
msgstr ""
#: pretix/control/forms/vouchers.py
#, python-format
msgid ""
"You cannot reduce the maximum number of redemptions to %(max_usages)s, "
"because at least one of the selected vouchers has already been redeemed "
"%(max_redeemed)s times."
msgstr ""
#: pretix/control/forms/vouchers.py
msgid ""
"You cannot create a voucher that allows selection of a quota but has no date "
"selected."
msgstr ""
#: pretix/control/forms/vouchers.py
msgid "The selected quota does not match the selected subevent."
msgstr ""
#: pretix/control/forms/vouchers.py
msgid "There is no sufficient quota available to perform this change."
msgstr ""
#: pretix/control/forms/vouchers.py
msgid ""
"Changing the maximum number of usages in bulk is not supported if any of the "
"selected vouchers is assigned a seat."
msgstr ""
#: pretix/control/forms/vouchers.py
msgctxt "subevent"
msgid ""
"Changing the date in bulk is not supported if any of the selected vouchers "
"is assigned a seat."
msgstr ""
#: pretix/control/forms/vouchers.py
msgid ""
"Changing the product to a quota is not supported if any of the selected "
"vouchers is assigned a seat."
msgstr ""
#: pretix/control/forms/vouchers.py
msgid ""
"This change cannot be completed because not all assigned seats of the "
"vouchers are still available"
msgstr ""
#: pretix/control/forms/vouchers.py
msgid "Codes"
msgstr ""
@@ -16430,6 +16340,10 @@ msgstr ""
msgid "Account history"
msgstr ""
#: pretix/control/navigation.py
msgid "All users"
msgstr ""
#: pretix/control/navigation.py
#: pretix/control/templates/pretixcontrol/user/staff_session_list.html
msgid "Admin sessions"
@@ -16698,7 +16612,6 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/users/create.html
#: pretix/control/templates/pretixcontrol/users/form.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk_edit.html
#: pretix/control/templates/pretixcontrol/vouchers/detail.html
#: pretix/control/templates/pretixcontrol/waitinglist/edit.html
#: pretix/plugins/autocheckin/templates/pretixplugins/autocheckin/add.html
@@ -17116,8 +17029,8 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/checkin/checkins.html
#: pretix/control/templates/pretixcontrol/checkin/index.html
#: pretix/control/templates/pretixcontrol/checkin/lists.html
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/fragment_log_filter_form.html
#: pretix/control/templates/pretixcontrol/items/question.html
#: pretix/control/templates/pretixcontrol/items/quotas.html
#: pretix/control/templates/pretixcontrol/orders/index.html
@@ -17128,6 +17041,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/organizers/devices.html
#: pretix/control/templates/pretixcontrol/organizers/giftcards.html
#: pretix/control/templates/pretixcontrol/organizers/index.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
#: pretix/control/templates/pretixcontrol/organizers/outgoing_mails.html
#: pretix/control/templates/pretixcontrol/organizers/reusable_media.html
#: pretix/control/templates/pretixcontrol/organizers/teams.html
@@ -17262,7 +17176,6 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/organizers/devices.html
#: pretix/control/templates/pretixcontrol/organizers/outgoing_mails.html
#: pretix/control/templates/pretixcontrol/subevents/index.html
#: pretix/control/templates/pretixcontrol/vouchers/index.html
#: pretix/control/templates/pretixcontrol/waitinglist/index.html
msgid "Select all results on other pages as well"
msgstr ""
@@ -17818,22 +17731,6 @@ msgstr ""
msgid "We found an SPF record on your domain that includes this system. Great!"
msgstr ""
#: pretix/control/templates/pretixcontrol/email_setup_simple.html
msgid "Your new DKIM record should be set up as a CNAME record like this:"
msgstr ""
#: pretix/control/templates/pretixcontrol/email_setup_simple.html
msgid "We found a DKIM record on your domain for this system. Great!"
msgstr ""
#: pretix/control/templates/pretixcontrol/email_setup_simple.html
msgid "Your new DMARC record could look like this:"
msgstr ""
#: pretix/control/templates/pretixcontrol/email_setup_simple.html
msgid "We found a DMARC record on your domain for this system. Great!"
msgstr ""
#: pretix/control/templates/pretixcontrol/email_setup_simple.html
msgid "Verification"
msgstr ""
@@ -17994,94 +17891,6 @@ msgid ""
"undeletable data, such as orders not performed in test mode."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_logs.html
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/includes/logs.html
#: pretix/control/templates/pretixcontrol/organizers/device_logs.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
msgid "Personal data was cleared from this log entry."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_logs.html
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/includes/logs.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
msgid "This change was performed by a pretix administrator."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_logs.html
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/includes/logs.html
#: pretix/control/templates/pretixcontrol/order/index.html
#: pretix/control/templates/pretixcontrol/organizers/device_logs.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
#: pretix/control/templates/pretixcontrol/search/payments.html
msgid "Inspect"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid ""
"This event contains <strong>overpaid orders</strong>, for example due to "
"duplicate payment attempts. You should review the cases and consider "
"refunding the overpaid amount to the user."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid "Show overpaid orders"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid ""
"This event contains <strong>pending refunds</strong> that you should take "
"care of."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid "Show pending refunds"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid ""
"This event contains <strong>requested cancellations</strong> that you should "
"take care of."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid "Show orders requesting cancellation"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid ""
"This event contains <strong>pending approvals</strong> that you should take "
"care of."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid "Show orders pending approval"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid ""
"This event contains <strong>fully paid orders</strong> that are not marked "
"as paid, probably because no quota was left at the time their payment "
"arrived. You should review the cases and consider either refunding the "
"customer or creating more space."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid "Show affected orders"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid ""
"Orders in this event could not be <strong>synced to an external system</"
"strong> as configured."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid "Show sync problems"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/delete.html
msgid ""
"This operation will destroy your event including all configuration, "
@@ -18196,6 +18005,69 @@ msgstr ""
msgid "Create QR code"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid ""
"This event contains <strong>overpaid orders</strong>, for example due to "
"duplicate payment attempts. You should review the cases and consider "
"refunding the overpaid amount to the user."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid "Show overpaid orders"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid ""
"This event contains <strong>pending refunds</strong> that you should take "
"care of."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid "Show pending refunds"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid ""
"This event contains <strong>requested cancellations</strong> that you should "
"take care of."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid "Show orders requesting cancellation"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid ""
"This event contains <strong>pending approvals</strong> that you should take "
"care of."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid "Show orders pending approval"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid ""
"This event contains <strong>fully paid orders</strong> that are not marked "
"as paid, probably because no quota was left at the time their payment "
"arrived. You should review the cases and consider either refunding the "
"customer or creating more space."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid "Show affected orders"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid ""
"Orders in this event could not be <strong>synced to an external system</"
"strong> as configured."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid "Show sync problems"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
#: pretix/control/templates/pretixcontrol/order/index.html
msgid "Update comment"
@@ -18370,6 +18242,44 @@ msgstr ""
msgid "Enable test mode"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
msgid "All actions"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/logs.html
msgid "Team actions"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/logs.html
msgid "Customer actions"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/event/logs_embed.html
#: pretix/control/templates/pretixcontrol/includes/logs.html
#: pretix/control/templates/pretixcontrol/organizers/device_logs.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
msgid "Personal data was cleared from this log entry."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/event/logs_embed.html
#: pretix/control/templates/pretixcontrol/includes/logs.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
msgid "This change was performed by a pretix administrator."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/event/logs_embed.html
#: pretix/control/templates/pretixcontrol/includes/logs.html
#: pretix/control/templates/pretixcontrol/order/index.html
#: pretix/control/templates/pretixcontrol/organizers/device_logs.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
#: pretix/control/templates/pretixcontrol/search/payments.html
msgid "Inspect"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/organizers/device_logs.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
@@ -19268,20 +19178,6 @@ msgstr ""
msgid "More quotas"
msgstr ""
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/views/dashboards.py
msgid "Shop disabled"
msgstr ""
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/subevents/detail.html
#: pretix/control/templates/pretixcontrol/subevents/index.html
#: pretix/control/views/dashboards.py
msgid "On sale"
msgstr ""
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
msgid "Open event dashboard"
@@ -19292,10 +19188,6 @@ msgctxt "typography"
msgid "The quick brown fox jumps over the lazy dog."
msgstr ""
#: pretix/control/templates/pretixcontrol/fragment_log_filter_form.html
msgid "Specific object selected"
msgstr ""
#: pretix/control/templates/pretixcontrol/fragment_quota_box.html
#: pretix/control/templates/pretixcontrol/fragment_quota_box_paid.html
msgid "Quota:"
@@ -20310,7 +20202,6 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/items/quota_bulk_edit.html
#: pretix/control/templates/pretixcontrol/organizers/device_bulk_edit.html
#: pretix/control/templates/pretixcontrol/subevents/bulk_edit.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk_edit.html
#, python-format
msgid "%(number)s selected"
msgstr ""
@@ -20397,7 +20288,6 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/items/quotas.html
#: pretix/control/templates/pretixcontrol/organizers/devices.html
#: pretix/control/templates/pretixcontrol/subevents/index.html
#: pretix/control/templates/pretixcontrol/vouchers/index.html
msgid "Edit selected"
msgstr ""
@@ -20694,13 +20584,6 @@ msgid ""
"the customer account."
msgstr ""
#: pretix/control/templates/pretixcontrol/order/change.html
#: pretix/control/views/orders.py
msgid ""
"Ticket secrets of order positions that have been used to issue a gift card "
"can not be changed. Only the link will be changed in this case."
msgstr ""
#: pretix/control/templates/pretixcontrol/order/change.html
msgid ""
"Removing or splitting this position will also remove or split all add-ons to "
@@ -21113,6 +20996,11 @@ msgstr ""
msgid "Create a refund"
msgstr ""
#: pretix/control/templates/pretixcontrol/order/index.html
#: pretix/control/templates/pretixcontrol/orders/refunds.html
msgid "Source"
msgstr ""
#: pretix/control/templates/pretixcontrol/order/index.html
msgid "Cancel transfer"
msgstr ""
@@ -22189,7 +22077,6 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/organizers/device_bulk_edit.html
#: pretix/control/templates/pretixcontrol/organizers/device_edit.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk_edit.html
#: pretix/control/templates/pretixcontrol/vouchers/detail.html
msgid "Advanced settings"
msgstr ""
@@ -24346,13 +24233,11 @@ msgid "Copy codes"
msgstr ""
#: pretix/control/templates/pretixcontrol/vouchers/bulk.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk_edit.html
#: pretix/control/templates/pretixcontrol/vouchers/detail.html
msgid "Voucher details"
msgstr ""
#: pretix/control/templates/pretixcontrol/vouchers/bulk.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk_edit.html
#: pretix/control/templates/pretixcontrol/vouchers/detail.html
msgid ""
"If you choose \"any product\" for a specific quota and choose to reserve "
@@ -24360,10 +24245,6 @@ msgid ""
"voucher holder if another quota associated with the product is sold out!"
msgstr ""
#: pretix/control/templates/pretixcontrol/vouchers/bulk_edit.html
msgid "Change multiple vouchers"
msgstr ""
#: pretix/control/templates/pretixcontrol/vouchers/delete.html
#: pretix/control/templates/pretixcontrol/vouchers/detail.html
msgid "Delete voucher"
@@ -24703,8 +24584,7 @@ msgstr ""
#, python-brace-format
msgid ""
"You cannot accept the invitation for \"{}\" as you already are part of this "
"team. If you want to add a different user or create a new account, log out "
"and click the invitation link again."
"team."
msgstr ""
#: pretix/control/views/auth.py
@@ -25307,30 +25187,6 @@ msgid ""
"record."
msgstr ""
#: pretix/control/views/mailsetup.py
msgid ""
"We could not find a CNAME record pointing to our DKIM key for domain you are "
"trying to use. This means that there is a very high change most of the "
"emails will be rejected or marked as spam. We strongly recommend setting up "
"DKIM through a CNAME record. You can do so through the DNS settings at the "
"provider you registered your domain with."
msgstr ""
#: pretix/control/views/mailsetup.py
msgid ""
"We found a CNAME record for a DKIM key, but it is not pointing to the right "
"location. This means that there is a very high chance most of the emails "
"will be rejected or marked as spam. You should update the DNS settings of "
"your domain."
msgstr ""
#: pretix/control/views/mailsetup.py
msgid ""
"We did not find DMARC record for your domain. This means that there is a "
"very high chance most of the emails will be rejected or marked as spam. You "
"should update the DNS settings of your domain."
msgstr ""
#: pretix/control/views/mailsetup.py
msgid "The verification code was incorrect, please try again."
msgstr ""
@@ -26388,7 +26244,6 @@ msgid "Macao"
msgstr ""
#: pretix/helpers/daterange.py
#: pretix/presale/templates/pretixpresale/event/fragment_subevent_list.html
#: pretix/presale/templates/pretixpresale/fragment_calendar.html
#: pretix/presale/templates/pretixpresale/fragment_week_calendar.html
#: pretix/presale/templates/pretixpresale/organizers/index.html
@@ -27576,6 +27431,11 @@ msgstr ""
msgid "PayPal account"
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
#, python-brace-format
msgid "<a target=\"_blank\" rel=\"noopener\" href=\"{docs_url}\">{text}</a>"
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid "Click here for a tutorial on how to obtain the required keys"
msgstr ""
@@ -28210,13 +28070,8 @@ msgstr ""
#: pretix/plugins/returnurl/views.py
msgid ""
"Redirection will only be allowed to URLs that start with one of these "
"prefixes. Enter one allowed URL prefix per line. URL prefixes must include a "
"slash after the hostname."
msgstr ""
#: pretix/plugins/returnurl/views.py
msgid ""
"All values must be URLs that include at last one slash after the hostname."
"prefixes. Enter one or more allowed URL prefix per line. URL prefixes must "
"include a slash after the hostname."
msgstr ""
#: pretix/plugins/sendmail/apps.py
File diff suppressed because it is too large Load Diff
+183 -132
View File
@@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-06 15:52+0000\n"
"PO-Revision-Date: 2026-07-13 11:28+0000\n"
"Last-Translator: ahmed badr <ahmedbadr@oma.com.eg>\n"
"PO-Revision-Date: 2021-09-15 11:22+0000\n"
"Last-Translator: Mohamed Tawfiq <mtawfiq@wafyapp.com>\n"
"Language-Team: Arabic <https://translate.pretix.eu/projects/pretix/pretix-js/"
"ar/>\n"
"Language: ar\n"
@@ -18,7 +18,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
"&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n"
"X-Generator: Weblate 2026.7.1\n"
"X-Generator: Weblate 4.8\n"
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js
msgid "Marked as paid"
@@ -30,110 +30,112 @@ msgstr "تعليق:"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js
msgid "PayPal"
msgstr "باي بال"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js
msgid "Venmo"
msgstr "Venmo"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js
#: pretix/static/pretixpresale/js/walletdetection.js
msgid "Apple Pay"
msgstr "Apple Pay"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js
msgid "Itaú"
msgstr "إيتاو"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js
msgid "PayPal Credit"
msgstr "الائتمان من PayPal"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js
msgid "Credit Card"
msgstr "بطاقة الائتمان"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js
msgid "PayPal Pay Later"
msgstr "الدفع لاحقًا عبر PayPal"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js
msgid "iDEAL | Wero"
msgstr "iDEAL | التحدي"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js
msgid "SEPA Direct Debit"
msgstr "الخصم المباشر في منطقة الدفع الموحدة (SEPA)"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js
msgid "Bancontact"
msgstr "بانكونتاكت"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js
msgid "giropay"
msgstr "giropay"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js
msgid "SOFORT"
msgstr "فوراً"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js
#, fuzzy
#| msgid "Yes"
msgid "eps"
msgstr قاط إضافية"
msgstr عم"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js
msgid "MyBank"
msgstr "بنكي"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js
msgid "Przelewy24"
msgstr "Przelewy24"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js
msgid "Verkkopankki"
msgstr "الخدمات المصرفية عبر الإنترنت"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js
msgid "PayU"
msgstr "الدفع لك"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js
msgid "BLIK"
msgstr "BLIK"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js
msgid "Trustly"
msgstr "Trustly"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js
msgid "Zimpler"
msgstr "Zimpler"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js
msgid "Maxima"
msgstr "الأعظم"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js
msgid "OXXO"
msgstr "OXXO"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js
msgid "Boleto"
msgstr "تذكرة"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js
msgid "WeChat Pay"
msgstr "WeChat Pay"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js
msgid "Mercado Pago"
msgstr "Mercado Pago"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/i18n.ts
#: pretix/static/pretixpresale/js/ui/cart.js
msgid "Continue"
msgstr "تابع"
msgstr "المتابعة"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js
@@ -142,7 +144,7 @@ msgstr "جاري تأكيد الدفع الخاص بك …"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js
msgid "Payment method unavailable"
msgstr "طريقة الدفع غير متاحة"
msgstr ""
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js
msgid "Placed orders"
@@ -154,11 +156,11 @@ msgstr "الطلبات المدفوعة"
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js
msgid "Attendees (ordered)"
msgstr "الحاضرون (حسب الترتيب)"
msgstr ""
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js
msgid "Attendees (paid)"
msgstr "الحاضرون (الذين دفعوا رسوم الاشتراك)"
msgstr ""
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js
msgid "Total revenue"
@@ -190,7 +192,7 @@ msgstr "تبديل قائمة الدخول"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/i18n.ts
msgid "Search results"
msgstr "نتائج البحث"
msgstr "البحث في النتائج"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/i18n.ts
msgid "No tickets found"
@@ -234,15 +236,15 @@ msgstr "غير مدفوع"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/i18n.ts
msgid "Canceled"
msgstr "تم إلغاؤه"
msgstr "ملغاة"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/i18n.ts
msgid "Confirmed"
msgstr "تم التأكيد"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/i18n.ts
msgid "Approval pending"
msgstr "في انتظار الموافقة"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/i18n.ts
msgid "Redeemed"
@@ -250,11 +252,11 @@ msgstr "مستخدم"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/i18n.ts
msgid "Cancel"
msgstr "إلغاء"
msgstr "قم بالإلغاء"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/i18n.ts
msgid "Ticket not paid"
msgstr "التذكرة لم يتم دفع ثمنها"
msgstr "لم يتم دفع قيمة التذكرة"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/i18n.ts
msgid "This ticket is not yet paid. Do you want to continue anyways?"
@@ -274,19 +276,23 @@ msgstr "تم تسجيل الخروج"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/i18n.ts
msgid "Ticket already used"
msgstr "تم استخدام التذكرة بالفعل"
msgstr "تم استخدام التذكرة مسبقا"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/i18n.ts
msgid "Information required"
msgstr "المعلومات المطلوبة"
msgstr "معلومات مطلوبة"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/i18n.ts
#, fuzzy
#| msgid "Unknown error."
msgid "Unknown ticket"
msgstr "تذكرة غير معروفة"
msgstr "خطأ غير معروف."
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/i18n.ts
#, fuzzy
#| msgid "Entry not allowed"
msgid "Ticket type not allowed here"
msgstr "نوع تذكرة الدخول غير مسموح به هنا"
msgstr "إدخال غير مسموح"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/i18n.ts
msgid "Entry not allowed"
@@ -294,13 +300,17 @@ msgstr "إدخال غير مسموح"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/i18n.ts
msgid "Ticket code revoked/changed"
msgstr "تم إلغاء/تغيير رمز التذكرة"
msgstr "تم إلغاء رمز التذكرة أو تبديله"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/i18n.ts
#, fuzzy
#| msgid "Ticket not paid"
msgid "Ticket blocked"
msgstr "التذكرة غير محجوبة"
msgstr "لم يتم دفع قيمة التذكرة"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/i18n.ts
#, fuzzy
#| msgid "Ticket not paid"
msgid "Ticket not valid at this time"
msgstr "لم يتم دفع قيمة التذكرة"
@@ -310,11 +320,11 @@ msgstr "تم إلغاء الطلب"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/i18n.ts
msgid "Ticket code is ambiguous on list"
msgstr "رمز التذكرة غير واضح في القائمة"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/i18n.ts
msgid "Order not approved"
msgstr "لم تتم الموافقة على الطلب"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/i18n.ts
msgid "Checked-in Tickets"
@@ -338,9 +348,12 @@ msgstr "نعم"
#: pretix/static/pretixcontrol/js/ui/question.js
#: pretix/static/pretixpresale/js/ui/questions.js
msgid "No"
msgstr "من"
msgstr "لا"
#: pretix/static/lightbox/js/lightbox.js
#, fuzzy
#| msgctxt "widget"
#| msgid "Close"
msgid "close"
msgstr "إغلاق"
@@ -395,7 +408,7 @@ msgstr ""
#: pretix/static/pretixbase/js/asynctask.js
msgid "We are processing your request …"
msgstr "نحن نقوم بمعالجة طلبك …"
msgstr "جاري معالجة طلبك …"
#: pretix/static/pretixbase/js/asynctask.js
msgid ""
@@ -408,7 +421,7 @@ msgstr ""
#: pretix/static/pretixbase/js/asynctask.js
msgid "If this takes longer than a few minutes, please contact us."
msgstr "إذا استغرق ذلك أكثر من بضع دقائق، يرجى الاتصال بنا."
msgstr ""
#: pretix/static/pretixbase/js/asynctask.js
msgid "Close message"
@@ -424,11 +437,11 @@ msgstr "للنسخ اضغط Ctrl + C!"
#: pretix/static/pretixcontrol/js/ui/checkinrules/App.vue
msgid "Edit"
msgstr "تحرير"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules/App.vue
msgid "Visualize"
msgstr "تصور"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules/App.vue
msgid ""
@@ -436,13 +449,10 @@ msgid ""
"or variations are not contained in any of your rule parts so people with "
"these tickets will not get in:"
msgstr ""
"تقوم القاعدة الخاصة بك دائمًا بالتصفية حسب المنتج أو النوع، لكن المنتجات أو "
"الأنواع التالية غير مدرجة في أي من أجزاء القاعدة الخاصة بك، لذا لن يتم قبول "
"الأشخاص الذين يحملون هذه التذاكر:"
#: pretix/static/pretixcontrol/js/ui/checkinrules/App.vue
msgid "Please double-check if this was intentional."
msgstr "يرجى التأكد مرة أخرى مما إذا كان ذلك مقصودًا أم لا."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules/constants.ts
msgid "All of the conditions below (AND)"
@@ -482,21 +492,21 @@ msgstr "أضف شرطا"
#: pretix/static/pretixcontrol/js/ui/checkinrules/constants.ts
msgid "minutes"
msgstr "دقائق"
msgstr "الدقائق"
#: pretix/static/pretixcontrol/js/ui/checkinrules/constants.ts
msgid "Duplicate"
msgstr "مكرر"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules/constants.ts
msgctxt "entry_status"
msgid "present"
msgstr "حاضر"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules/constants.ts
msgctxt "entry_status"
msgid "absent"
msgstr "غائب"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules/constants.ts
msgid "is one of"
@@ -512,11 +522,11 @@ msgstr "بعد"
#: pretix/static/pretixcontrol/js/ui/checkinrules/constants.ts
msgid "="
msgstr "="
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules/constants.ts
msgid "Product"
msgstr "المنتج"
msgstr "منتج"
#: pretix/static/pretixcontrol/js/ui/checkinrules/constants.ts
msgid "Product variation"
@@ -524,7 +534,7 @@ msgstr "نوع المنتج"
#: pretix/static/pretixcontrol/js/ui/checkinrules/constants.ts
msgid "Gate"
msgstr "الشارع"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules/constants.ts
msgid "Current date and time"
@@ -532,11 +542,11 @@ msgstr "التاريخ والوقت الحالي"
#: pretix/static/pretixcontrol/js/ui/checkinrules/constants.ts
msgid "Current day of the week (1 = Monday, 7 = Sunday)"
msgstr "اليوم الحالي من الأسبوع (1 = الاثنين، 7 = الأحد)"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules/constants.ts
msgid "Current entry status"
msgstr "الحالة الحالية للطلب"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules/constants.ts
msgid "Number of previous entries"
@@ -547,40 +557,48 @@ msgid "Number of previous entries since midnight"
msgstr "عدد المدخلات السابقة قبل منتصف الليل"
#: pretix/static/pretixcontrol/js/ui/checkinrules/constants.ts
#, fuzzy
#| msgid "Number of previous entries"
msgid "Number of previous entries since"
msgstr "عدد الإدخالات السابقة منذ"
msgstr "عدد المدخلات السابقة"
#: pretix/static/pretixcontrol/js/ui/checkinrules/constants.ts
#, fuzzy
#| msgid "Number of previous entries"
msgid "Number of previous entries before"
msgstr "عدد الإدخالات السابقة قبل"
msgstr "عدد المدخلات السابقة"
#: pretix/static/pretixcontrol/js/ui/checkinrules/constants.ts
msgid "Number of days with a previous entry"
msgstr "عدد الأيام التي تحتوي على مدخل سابق"
#: pretix/static/pretixcontrol/js/ui/checkinrules/constants.ts
#, fuzzy
#| msgid "Number of days with a previous entry"
msgid "Number of days with a previous entry since"
msgstr "عدد الأيام التي تحتوي على قيد سابق منذ"
msgstr "عدد الأيام التي تحتوي على مدخل سابق"
#: pretix/static/pretixcontrol/js/ui/checkinrules/constants.ts
#, fuzzy
#| msgid "Number of days with a previous entry"
msgid "Number of days with a previous entry before"
msgstr "عدد الأيام التي يوجد فيها قيد سابق قبل ذلك"
msgstr "عدد الأيام التي تحتوي على مدخل سابق"
#: pretix/static/pretixcontrol/js/ui/checkinrules/constants.ts
msgid "Minutes since last entry (-1 on first entry)"
msgstr "عدد الدقائق منذ آخر تسجيل (-1 عند التسجيل الأول)"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules/constants.ts
msgid "Minutes since first entry (-1 on first entry)"
msgstr "عدد الدقائق منذ أول دخول (-1 عند أول دخول)"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules/django-interop.ts
msgid "Error: Product not found!"
msgstr "خطأ: لم يتم العثور على المنتج!"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules/django-interop.ts
msgid "Error: Variation not found!"
msgstr "خطأ: لم يتم العثور على النسخة!"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js
msgid "Check-in QR"
@@ -595,12 +613,16 @@ msgid "Group of objects"
msgstr "مجموعة من العناصر"
#: pretix/static/pretixcontrol/js/ui/editor.js
#, fuzzy
#| msgid "Text object"
msgid "Text object (deprecated)"
msgstr "كائن نصي (مهمل)"
msgstr "عنصر نص"
#: pretix/static/pretixcontrol/js/ui/editor.js
#, fuzzy
#| msgid "Text object"
msgid "Text box"
msgstr "مربع نصي"
msgstr نصر نص"
#: pretix/static/pretixcontrol/js/ui/editor.js
msgid "Barcode area"
@@ -647,28 +669,28 @@ msgid "Unknown error."
msgstr "خطأ غير معروف."
#: pretix/static/pretixcontrol/js/ui/main.js
#, fuzzy
#| msgid "Your color has great contrast and is very easy to read!"
msgid "Your color has great contrast and will provide excellent accessibility."
msgstr "يتميز لونك بتباين رائع ويسهل قراءته للغاية! وسيوفر إمكانية وصول ممتازة."
msgstr "اللون يتمتع بتباين كبير وتسهل قراءته!"
#: pretix/static/pretixcontrol/js/ui/main.js
#, fuzzy
#| msgid "Your color has decent contrast and is probably good-enough to read!"
msgid ""
"Your color has decent contrast and is sufficient for minimum accessibility "
"requirements."
msgstr ""
"يتميز لونك بتباين جيد، ومن المرجح أنه مناسب للقراءة! وهو كافٍ لتلبية الحد "
"الأدنى من متطلبات سهولة الوصول."
msgstr "اللون يحظى بتباين معقول ويمكن أن يكون مناسب للقراءة!"
#: pretix/static/pretixcontrol/js/ui/main.js
msgid ""
"Your color has insufficient contrast to white. Accessibility of your site "
"will be impacted."
msgstr ""
"اللون الذي اخترته لا يتمتع بتباين كافٍ مع اللون الأبيض. وسيؤثر ذلك على إمكانية "
"الوصول إلى موقعك."
#: pretix/static/pretixcontrol/js/ui/main.js
msgid "Search query"
msgstr "استعلام البحث"
msgstr "البحث في الاستفسارات"
#: pretix/static/pretixcontrol/js/ui/main.js
msgid "All"
@@ -684,11 +706,11 @@ msgstr "المختارة فقط"
#: pretix/static/pretixcontrol/js/ui/main.js
msgid "Enter page number between 1 and %(max)s."
msgstr "أدخل رقم الصفحة بين 1 و %(max)s."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js
msgid "Invalid page number."
msgstr "رقم الصفحة غير صحيح."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js
msgid "Use a different name internally"
@@ -707,8 +729,10 @@ msgid "Calculating default price…"
msgstr "حساب السعر الافتراضي…"
#: pretix/static/pretixcontrol/js/ui/plugins.js
#, fuzzy
#| msgid "Search results"
msgid "No results"
msgstr "البحث: لا توجد نتائج"
msgstr "البحث في النتائج"
#: pretix/static/pretixcontrol/js/ui/question.js
msgid "Others"
@@ -716,7 +740,7 @@ msgstr "غير ذلك"
#: pretix/static/pretixcontrol/js/ui/question.js
msgid "Count"
msgstr "العدد"
msgstr "احسب"
#: pretix/static/pretixcontrol/js/ui/subevent.js
msgid "(one more date)"
@@ -729,12 +753,12 @@ msgstr[4] "أيام عديدة"
msgstr[5] "أخرى"
#: pretix/static/pretixpresale/js/ui/cart.js
#, fuzzy
#| msgid "The items in your cart are no longer reserved for you."
msgid ""
"The items in your cart are no longer reserved for you. You can still "
"complete your order as long as theyre available."
msgstr ""
"لم تعد المنتجات الموجودة في سلة التسوق محجوزة لك. لا يزال بإمكانك إتمام طلبك "
"طالما كانت هذه المنتجات متوفرة."
msgstr "لم تعد العناصر الموجودة في عربة التسوق الخاصة بك محجوزة لك."
#: pretix/static/pretixpresale/js/ui/cart.js
msgid "Cart expired"
@@ -742,9 +766,13 @@ msgstr "انتهت صلاحية عربة التسوق"
#: pretix/static/pretixpresale/js/ui/cart.js
msgid "Your cart is about to expire."
msgstr "سوف تنتهي صلاحية سلة التسوق الخاصة بك قريبًا."
msgstr ""
#: pretix/static/pretixpresale/js/ui/cart.js
#, fuzzy
#| msgid "The items in your cart are reserved for you for one minute."
#| msgid_plural ""
#| "The items in your cart are reserved for you for {num} minutes."
msgid "The items in your cart are reserved for you for one minute."
msgid_plural "The items in your cart are reserved for you for {num} minutes."
msgstr[0] "سيتم حجز العناصر لك في سلة التسوق لمدة {num}."
@@ -755,24 +783,26 @@ msgstr[4] "سيتم حجز العناصر لك في سلة التسوق لدقا
msgstr[5] "سيتم حجز العناصر لك في سلة التسوق لمدة {num}."
#: pretix/static/pretixpresale/js/ui/cart.js
#, fuzzy
#| msgid "Cart expired"
msgid "Your cart has expired."
msgstr "انتهت صلاحية عربة التسوق"
#: pretix/static/pretixpresale/js/ui/cart.js
#, fuzzy
#| msgid "The items in your cart are no longer reserved for you."
msgid ""
"The items in your cart are no longer reserved for you. You can still "
"complete your order as long as they're available."
msgstr ""
"لم تعد المنتجات الموجودة في سلة التسوق محجوزة لك. لا يزال بإمكانك إتمام طلبك "
"طالما كانت هذه المنتجات متوفرة."
msgstr "لم تعد العناصر الموجودة في عربة التسوق الخاصة بك محجوزة لك."
#: pretix/static/pretixpresale/js/ui/cart.js
msgid "Do you want to renew the reservation period?"
msgstr "هل ترغب في تمديد فترة الحجز؟"
msgstr ""
#: pretix/static/pretixpresale/js/ui/cart.js
msgid "Renew reservation"
msgstr "تجديد الحجز"
msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js
msgid "The organizer keeps %(currency)s %(amount)s"
@@ -792,77 +822,82 @@ msgstr "التوقيت المحلي:"
#: pretix/static/pretixpresale/js/walletdetection.js
msgid "Google Pay"
msgstr "Google Pay"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Quantity"
msgstr "الكمية"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Decrease quantity"
msgstr "تقليل الكمية"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Increase quantity"
msgstr "زيادة الكمية"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Filter events by"
msgstr "تصفية الأحداث حسب"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Filter"
msgstr "فلتر"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Price"
msgstr "السعر"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "Original price: %s"
msgstr "السعر الأصلي: %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "New price: %s"
msgstr "السعر الجديد: %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, fuzzy
#| msgid "Selected only"
msgctxt "widget"
msgid "Select"
msgstr "المختارة فقط"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
#, fuzzy, javascript-format
#| msgid "Selected only"
msgctxt "widget"
msgid "Select %s"
msgstr "تم اختيار %s فقط"
msgstr "المختارة فقط"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
#, fuzzy, javascript-format
#| msgctxt "widget"
#| msgid "See variations"
msgctxt "widget"
msgid "Select variant %s"
msgstr "اختر النوع %s"
msgstr "أنظر إلى الاختلافات"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
@@ -905,7 +940,7 @@ msgstr "من %(currency) s %(price)s"
#, javascript-format
msgctxt "widget"
msgid "Image of %s"
msgstr "صورة لـ %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
@@ -946,21 +981,27 @@ msgstr "متوفرة مع القسيمة فقط"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, fuzzy
#| msgctxt "widget"
#| msgid "currently available: %s"
msgctxt "widget"
msgid "Not yet available"
msgstr "حاليًا غير متوفر: %s"
msgstr "متوفر حاليا: %s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Not available anymore"
msgstr "لم يعد متوفراً"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, fuzzy
#| msgctxt "widget"
#| msgid "currently available: %s"
msgctxt "widget"
msgid "Currently not available"
msgstr "غير متوفر حاليًا: %s"
msgstr "متوفر حاليا: %s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
@@ -988,20 +1029,24 @@ msgid ""
"There are currently a lot of users in this ticket shop. Please open the shop "
"in a new tab to continue."
msgstr ""
"يوجد حالياً عدد كبير من المستخدمين في متجر التذاكر هذا. يرجى فتح المتجر في "
"علامة تبويب جديدة للمتابعة."
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, fuzzy
#| msgctxt "widget"
#| msgid "Close ticket shop"
msgctxt "widget"
msgid "Open ticket shop"
msgstr "إغلاق/فتح متجر التذاكر"
msgstr "إغلاق متجر التذاكر"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, fuzzy
#| msgctxt "widget"
#| msgid "Resume checkout"
msgctxt "widget"
msgid "Checkout"
msgstr "استئناف عملية الدفع"
msgstr "استئناف الدفع"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
@@ -1016,9 +1061,6 @@ msgid ""
"We could not create your cart, since there are currently too many users in "
"this ticket shop. Please click \"Continue\" to retry in a new tab."
msgstr ""
"لم نتمكن من إنشاء سلة التسوق الخاصة بك، نظرًا لوجود عدد كبير جدًّا من "
"المستخدمين حاليًّا في متجر التذاكر هذا. يرجى النقر على «متابعة» لإعادة المحاولة "
"في علامة تبويب جديدة."
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
@@ -1068,15 +1110,18 @@ msgstr "إغلاق"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, fuzzy
#| msgctxt "widget"
#| msgid "Resume checkout"
msgctxt "widget"
msgid "Close checkout"
msgstr "إغلاق عملية الدفع"
msgstr "استئناف الدفع"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "You cannot cancel this operation. Please wait for loading to finish."
msgstr "لا يمكنك إلغاء هذه العملية. يرجى الانتظار حتى ينتهي التحميل."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
@@ -1086,15 +1131,21 @@ msgstr "استمرار"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, fuzzy
#| msgctxt "widget"
#| msgid "See variations"
msgctxt "widget"
msgid "Show variants"
msgstr "انظر الاختلافات"
msgstr "أنظر إلى الاختلافات"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, fuzzy
#| msgctxt "widget"
#| msgid "See variations"
msgctxt "widget"
msgid "Hide variants"
msgstr "إخفاء الاختلافات"
msgstr "أنظر إلى الاختلافات"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
@@ -1152,11 +1203,11 @@ msgid ""
"add yourself to the waiting list. We will then notify if seats are available "
"again."
msgstr ""
"تم بيع جميع فئات التذاكر أو بعضها حاليًا. إذا أردت، يمكنك إضافة اسمك إلى "
"قائمة الانتظار. وسنقوم بإخطارك إذا توفرت مقاعد مرة أخرى."
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, fuzzy
#| msgid "Load more"
msgctxt "widget"
msgid "Load more"
msgstr "تحميل المزيد"
@@ -1199,37 +1250,37 @@ msgstr "الأحد"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Monday"
msgstr "الاثنين"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Tuesday"
msgstr "الثلاثاء"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Wednesday"
msgstr "الأربعاء"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Thursday"
msgstr "الخميس"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Friday"
msgstr "الجمعة"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Saturday"
msgstr "السبت"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Sunday"
msgstr "الأحد"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
@@ -1254,7 +1305,7 @@ msgstr "أبريل"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "May"
msgstr "هناك"
msgstr "مايو"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
+222 -367
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-30 13:52+0000\n"
"POT-Creation-Date: 2026-07-07 09:30+0000\n"
"PO-Revision-Date: 2024-12-11 01:00+0000\n"
"Last-Translator: Neriman Memmedli <nerim4n@pm.me>\n"
"Language-Team: Azerbaijani <https://translate.pretix.eu/projects/pretix/"
@@ -19,6 +19,38 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.8.4\n"
#: htmlcov/d_daa1541d0cbf5e2b_dashboards_py.html
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/views/dashboards.py
msgid "Shop disabled"
msgstr ""
#: htmlcov/d_daa1541d0cbf5e2b_dashboards_py.html pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/subevents/detail.html
#: pretix/control/templates/pretixcontrol/subevents/index.html
msgid "Presale over"
msgstr ""
#: htmlcov/d_daa1541d0cbf5e2b_dashboards_py.html pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/subevents/detail.html
#: pretix/control/templates/pretixcontrol/subevents/index.html
msgid "Presale not started"
msgstr ""
#: htmlcov/d_daa1541d0cbf5e2b_dashboards_py.html
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/subevents/detail.html
#: pretix/control/templates/pretixcontrol/subevents/index.html
#: pretix/control/views/dashboards.py
msgid "On sale"
msgstr ""
#: pretix/_base_settings.py
msgid "English"
msgstr "İngiliscə"
@@ -1169,19 +1201,6 @@ msgstr ""
msgid "Download a spreadsheet of all currently registered customer accounts."
msgstr ""
#: pretix/base/exporters/customers.py pretix/base/permissions.py
#: pretix/control/navigation.py
#: pretix/control/templates/pretixcontrol/organizers/customers.html
msgid "Customers"
msgstr ""
#: pretix/base/exporters/customers.py pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/organizers/customer.html
#: pretix/presale/templates/pretixpresale/organizers/customer_memberships.html
#: pretix/presale/views/customer.py
msgid "Memberships"
msgstr ""
#: pretix/base/exporters/customers.py pretix/base/models/customers.py
#: pretix/control/templates/pretixcontrol/organizers/customer.html
#: pretix/control/templates/pretixcontrol/organizers/customers.html
@@ -1314,66 +1333,6 @@ msgstr ""
msgid "No"
msgstr ""
#: pretix/base/exporters/customers.py pretix/base/exporters/orderlist.py
#: pretix/base/models/memberships.py pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/event/live.html
msgid "Test mode"
msgstr ""
#: pretix/base/exporters/customers.py pretix/base/models/memberships.py
#: pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/orders/fragment_order_status.html
#: pretix/control/templates/pretixcontrol/orders/overview.html
#: pretix/control/templates/pretixcontrol/organizers/customer_membership.html
#: pretix/plugins/reports/exporters.py
#: pretix/presale/templates/pretixpresale/event/fragment_order_status.html
#: pretix/presale/templates/pretixpresale/organizers/customer_membership.html
#: pretix/presale/templates/pretixpresale/organizers/customer_memberships.html
msgid "Canceled"
msgstr ""
#: pretix/base/exporters/customers.py pretix/base/models/memberships.py
#: pretix/control/templates/pretixcontrol/organizers/customer.html
#: pretix/presale/templates/pretixpresale/organizers/customer_membership.html
msgid "Membership type"
msgstr ""
#: pretix/base/exporters/customers.py
msgid "Purchase ticket"
msgstr ""
#: pretix/base/exporters/customers.py pretix/base/exporters/orderlist.py
#: pretix/base/exporters/waitinglist.py pretix/base/forms/questions.py
#: pretix/base/models/memberships.py pretix/control/forms/rrule.py
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/order/index.html
#: pretix/control/templates/pretixcontrol/orders/refunds.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/search/payments.html
#: pretix/control/templates/pretixcontrol/user/staff_session_edit.html
#: pretix/control/templates/pretixcontrol/user/staff_session_list.html
#: pretix/plugins/checkinlists/exporters.py
msgid "Start date"
msgstr ""
#: pretix/base/exporters/customers.py
msgid "Start time"
msgstr ""
#: pretix/base/exporters/customers.py pretix/base/exporters/orderlist.py
#: pretix/base/exporters/waitinglist.py pretix/base/models/memberships.py
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/user/staff_session_edit.html
#: pretix/control/templates/pretixcontrol/user/staff_session_list.html
#: pretix/plugins/checkinlists/exporters.py
msgid "End date"
msgstr ""
#: pretix/base/exporters/customers.py
msgid "End time"
msgstr ""
#: pretix/base/exporters/dekodi.py pretix/base/exporters/invoices.py
msgctxt "export_category"
msgid "Invoices"
@@ -2201,6 +2160,30 @@ msgstr ""
msgid "Position ID"
msgstr ""
#: pretix/base/exporters/orderlist.py pretix/base/exporters/waitinglist.py
#: pretix/base/forms/questions.py pretix/base/models/memberships.py
#: pretix/control/forms/rrule.py
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/order/index.html
#: pretix/control/templates/pretixcontrol/orders/refunds.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/search/payments.html
#: pretix/control/templates/pretixcontrol/user/staff_session_edit.html
#: pretix/control/templates/pretixcontrol/user/staff_session_list.html
#: pretix/plugins/checkinlists/exporters.py
msgid "Start date"
msgstr ""
#: pretix/base/exporters/orderlist.py pretix/base/exporters/waitinglist.py
#: pretix/base/models/memberships.py
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/user/staff_session_edit.html
#: pretix/control/templates/pretixcontrol/user/staff_session_list.html
#: pretix/plugins/checkinlists/exporters.py
msgid "End date"
msgstr ""
#: pretix/base/exporters/orderlist.py pretix/base/exporters/waitinglist.py
#: pretix/base/modelimport_orders.py pretix/base/modelimport_vouchers.py
#: pretix/base/models/items.py pretix/base/models/vouchers.py
@@ -2592,6 +2575,12 @@ msgstr ""
msgid "Gift card code"
msgstr ""
#: pretix/base/exporters/orderlist.py pretix/base/models/memberships.py
#: pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/event/live.html
msgid "Test mode"
msgstr ""
#: pretix/base/exporters/orderlist.py pretix/base/models/organizer.py
#: pretix/control/forms/event.py pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/email_setup.html
@@ -2705,7 +2694,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/orders/overview.html
#: pretix/control/templates/pretixcontrol/organizers/customer.html
#: pretix/control/templates/pretixcontrol/organizers/giftcards.html
#: pretix/plugins/reports/exporters.py pretix/plugins/sendmail/forms.py
#: pretix/plugins/reports/exporters.py
#: pretix/presale/templates/pretixpresale/event/fragment_order_status.html
#: pretix/presale/templates/pretixpresale/organizers/customer_giftcards.html
msgid "Expired"
@@ -2871,7 +2860,7 @@ msgid "This combination of credentials is not known to our system."
msgstr ""
#: pretix/base/forms/auth.py pretix/base/forms/user.py
#: pretix/control/views/user.py pretix/presale/forms/customer.py
#: pretix/presale/forms/customer.py
msgid "For security reasons, please wait 5 minutes before you try again."
msgstr ""
@@ -3794,7 +3783,6 @@ msgstr ""
#: pretix/base/modelimport_vouchers.py pretix/base/models/vouchers.py
#: pretix/control/templates/pretixcontrol/vouchers/bulk.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk_edit.html
#: pretix/control/templates/pretixcontrol/vouchers/detail.html
#: pretix/control/views/vouchers.py
msgid "Price effect"
@@ -4412,8 +4400,8 @@ msgstr ""
#: pretix/base/models/event.py
msgid ""
"This will be used to let users know if the event is in a different timezone, "
"and to let us calculate the local time of a user."
"This will be used to let users know if the event is in a different timezone "
"and lets us calculate users local times."
msgstr ""
#: pretix/base/models/event.py pretix/base/models/organizer.py
@@ -5708,6 +5696,23 @@ msgstr ""
msgid "Number of times this membership can be used in a purchase."
msgstr ""
#: pretix/base/models/memberships.py pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/orders/fragment_order_status.html
#: pretix/control/templates/pretixcontrol/orders/overview.html
#: pretix/control/templates/pretixcontrol/organizers/customer_membership.html
#: pretix/plugins/reports/exporters.py
#: pretix/presale/templates/pretixpresale/event/fragment_order_status.html
#: pretix/presale/templates/pretixpresale/organizers/customer_membership.html
#: pretix/presale/templates/pretixpresale/organizers/customer_memberships.html
msgid "Canceled"
msgstr ""
#: pretix/base/models/memberships.py
#: pretix/control/templates/pretixcontrol/organizers/customer.html
#: pretix/presale/templates/pretixpresale/organizers/customer_membership.html
msgid "Membership type"
msgstr ""
#: pretix/base/models/orders.py
msgid "pending"
msgstr ""
@@ -6486,7 +6491,7 @@ msgstr ""
msgid "It is currently not possible to create vouchers for add-on products."
msgstr ""
#: pretix/base/models/vouchers.py pretix/control/forms/vouchers.py
#: pretix/base/models/vouchers.py
msgid ""
"You need to select a specific product or quota if this voucher should "
"reserve tickets."
@@ -6505,7 +6510,7 @@ msgid ""
"usages."
msgstr ""
#: pretix/base/models/vouchers.py pretix/control/forms/vouchers.py
#: pretix/base/models/vouchers.py
msgid ""
"If you want this voucher to block quota, you need to select a specific date."
msgstr ""
@@ -6974,12 +6979,6 @@ msgstr ""
msgid "This gift card was used in the meantime. Please try again."
msgstr ""
#: pretix/base/payment.py
msgid ""
"This payment provider exists for historical purposes only and is no longer "
"usable."
msgstr ""
#: pretix/base/pdf.py
msgid "Ticket code (barcode content)"
msgstr ""
@@ -7536,6 +7535,11 @@ msgid ""
"permissions."
msgstr ""
#: pretix/base/permissions.py pretix/control/navigation.py
#: pretix/control/templates/pretixcontrol/organizers/customers.html
msgid "Customers"
msgstr ""
#: pretix/base/permissions.py pretix/control/navigation.py
msgid "Devices"
msgstr ""
@@ -8661,12 +8665,6 @@ msgid ""
"card."
msgstr ""
#: pretix/base/services/orders.py
msgid ""
"You cannot change the ticket secret of a position that has been used to "
"issue a gift card."
msgstr ""
#: pretix/base/services/orders.py
#, python-brace-format
msgid ""
@@ -10199,11 +10197,11 @@ msgstr ""
msgid "We'll show this publicly to allow attendees to contact you."
msgstr ""
#: pretix/base/settings.py
#: pretix/base/settings.py pretix/control/forms/event.py
msgid "Contact URL"
msgstr ""
#: pretix/base/settings.py
#: pretix/base/settings.py pretix/control/forms/event.py
msgid ""
"If you set this, the footer contact link will point here instead of using "
"the email address above. Please note that you still need to add a contact "
@@ -11684,7 +11682,6 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/organizers/customer.html
#: pretix/control/templates/pretixcontrol/organizers/customer_membership.html
#: pretix/control/templates/pretixcontrol/organizers/customers.html
#: pretix/control/templates/pretixcontrol/organizers/devices.html
#: pretix/control/templates/pretixcontrol/organizers/giftcard.html
#: pretix/control/templates/pretixcontrol/organizers/giftcards.html
#: pretix/control/templates/pretixcontrol/organizers/reusable_media.html
@@ -12880,7 +12877,7 @@ msgstr ""
msgid "Valid orders"
msgstr ""
#: pretix/control/forms/filter.py pretix/plugins/sendmail/forms.py
#: pretix/control/forms/filter.py
msgid "Paid (or canceled with paid fee)"
msgstr ""
@@ -12904,7 +12901,7 @@ msgstr ""
msgid "Cancellations"
msgstr ""
#: pretix/control/forms/filter.py pretix/plugins/sendmail/forms.py
#: pretix/control/forms/filter.py
msgid "Canceled (fully)"
msgstr ""
@@ -13079,22 +13076,6 @@ msgstr ""
msgid "Inactive"
msgstr ""
#: pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/subevents/detail.html
#: pretix/control/templates/pretixcontrol/subevents/index.html
msgid "Presale not started"
msgstr ""
#: pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/subevents/detail.html
#: pretix/control/templates/pretixcontrol/subevents/index.html
msgid "Presale over"
msgstr ""
#: pretix/control/forms/filter.py
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/import_form.html
msgid "Date from"
@@ -13132,6 +13113,13 @@ msgstr ""
msgid "not yet activated"
msgstr ""
#: pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/organizers/customer.html
#: pretix/presale/templates/pretixpresale/organizers/customer_memberships.html
#: pretix/presale/views/customer.py
msgid "Memberships"
msgstr ""
#: pretix/control/forms/filter.py
msgid "Has no memberships"
msgstr ""
@@ -13359,36 +13347,6 @@ msgstr ""
msgid "Search email address or subject"
msgstr ""
#: pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/order/index.html
#: pretix/control/templates/pretixcontrol/orders/refunds.html
msgid "Source"
msgstr ""
#: pretix/control/forms/filter.py
msgid "All sources"
msgstr ""
#: pretix/control/forms/filter.py
msgid "Team actions"
msgstr ""
#: pretix/control/forms/filter.py
msgid "Customer actions"
msgstr ""
#: pretix/control/forms/filter.py
msgid "Device actions"
msgstr ""
#: pretix/control/forms/filter.py
msgid "User email"
msgstr ""
#: pretix/control/forms/filter.py pretix/control/navigation.py
msgid "All users"
msgstr ""
#: pretix/control/forms/global_settings.py
msgid "Additional footer text"
msgstr ""
@@ -14566,7 +14524,6 @@ msgstr ""
#: pretix/control/forms/renderers.py
#: pretix/control/templates/pretixcontrol/organizers/device_bulk_edit.html
#: pretix/control/templates/pretixcontrol/subevents/bulk_edit.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk_edit.html
msgctxt "form_bulk"
msgid "change"
msgstr ""
@@ -14680,53 +14637,6 @@ msgid ""
"should show them."
msgstr ""
#: pretix/control/forms/vouchers.py
#, python-format
msgid ""
"You cannot reduce the maximum number of redemptions to %(max_usages)s, "
"because at least one of the selected vouchers has already been redeemed "
"%(max_redeemed)s times."
msgstr ""
#: pretix/control/forms/vouchers.py
msgid ""
"You cannot create a voucher that allows selection of a quota but has no date "
"selected."
msgstr ""
#: pretix/control/forms/vouchers.py
msgid "The selected quota does not match the selected subevent."
msgstr ""
#: pretix/control/forms/vouchers.py
msgid "There is no sufficient quota available to perform this change."
msgstr ""
#: pretix/control/forms/vouchers.py
msgid ""
"Changing the maximum number of usages in bulk is not supported if any of the "
"selected vouchers is assigned a seat."
msgstr ""
#: pretix/control/forms/vouchers.py
msgctxt "subevent"
msgid ""
"Changing the date in bulk is not supported if any of the selected vouchers "
"is assigned a seat."
msgstr ""
#: pretix/control/forms/vouchers.py
msgid ""
"Changing the product to a quota is not supported if any of the selected "
"vouchers is assigned a seat."
msgstr ""
#: pretix/control/forms/vouchers.py
msgid ""
"This change cannot be completed because not all assigned seats of the "
"vouchers are still available"
msgstr ""
#: pretix/control/forms/vouchers.py
msgid "Codes"
msgstr ""
@@ -16432,6 +16342,10 @@ msgstr ""
msgid "Account history"
msgstr ""
#: pretix/control/navigation.py
msgid "All users"
msgstr ""
#: pretix/control/navigation.py
#: pretix/control/templates/pretixcontrol/user/staff_session_list.html
msgid "Admin sessions"
@@ -16700,7 +16614,6 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/users/create.html
#: pretix/control/templates/pretixcontrol/users/form.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk_edit.html
#: pretix/control/templates/pretixcontrol/vouchers/detail.html
#: pretix/control/templates/pretixcontrol/waitinglist/edit.html
#: pretix/plugins/autocheckin/templates/pretixplugins/autocheckin/add.html
@@ -17118,8 +17031,8 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/checkin/checkins.html
#: pretix/control/templates/pretixcontrol/checkin/index.html
#: pretix/control/templates/pretixcontrol/checkin/lists.html
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/fragment_log_filter_form.html
#: pretix/control/templates/pretixcontrol/items/question.html
#: pretix/control/templates/pretixcontrol/items/quotas.html
#: pretix/control/templates/pretixcontrol/orders/index.html
@@ -17130,6 +17043,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/organizers/devices.html
#: pretix/control/templates/pretixcontrol/organizers/giftcards.html
#: pretix/control/templates/pretixcontrol/organizers/index.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
#: pretix/control/templates/pretixcontrol/organizers/outgoing_mails.html
#: pretix/control/templates/pretixcontrol/organizers/reusable_media.html
#: pretix/control/templates/pretixcontrol/organizers/teams.html
@@ -17264,7 +17178,6 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/organizers/devices.html
#: pretix/control/templates/pretixcontrol/organizers/outgoing_mails.html
#: pretix/control/templates/pretixcontrol/subevents/index.html
#: pretix/control/templates/pretixcontrol/vouchers/index.html
#: pretix/control/templates/pretixcontrol/waitinglist/index.html
msgid "Select all results on other pages as well"
msgstr ""
@@ -17820,22 +17733,6 @@ msgstr ""
msgid "We found an SPF record on your domain that includes this system. Great!"
msgstr ""
#: pretix/control/templates/pretixcontrol/email_setup_simple.html
msgid "Your new DKIM record should be set up as a CNAME record like this:"
msgstr ""
#: pretix/control/templates/pretixcontrol/email_setup_simple.html
msgid "We found a DKIM record on your domain for this system. Great!"
msgstr ""
#: pretix/control/templates/pretixcontrol/email_setup_simple.html
msgid "Your new DMARC record could look like this:"
msgstr ""
#: pretix/control/templates/pretixcontrol/email_setup_simple.html
msgid "We found a DMARC record on your domain for this system. Great!"
msgstr ""
#: pretix/control/templates/pretixcontrol/email_setup_simple.html
msgid "Verification"
msgstr ""
@@ -17996,94 +17893,6 @@ msgid ""
"undeletable data, such as orders not performed in test mode."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_logs.html
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/includes/logs.html
#: pretix/control/templates/pretixcontrol/organizers/device_logs.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
msgid "Personal data was cleared from this log entry."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_logs.html
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/includes/logs.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
msgid "This change was performed by a pretix administrator."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_logs.html
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/includes/logs.html
#: pretix/control/templates/pretixcontrol/order/index.html
#: pretix/control/templates/pretixcontrol/organizers/device_logs.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
#: pretix/control/templates/pretixcontrol/search/payments.html
msgid "Inspect"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid ""
"This event contains <strong>overpaid orders</strong>, for example due to "
"duplicate payment attempts. You should review the cases and consider "
"refunding the overpaid amount to the user."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid "Show overpaid orders"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid ""
"This event contains <strong>pending refunds</strong> that you should take "
"care of."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid "Show pending refunds"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid ""
"This event contains <strong>requested cancellations</strong> that you should "
"take care of."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid "Show orders requesting cancellation"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid ""
"This event contains <strong>pending approvals</strong> that you should take "
"care of."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid "Show orders pending approval"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid ""
"This event contains <strong>fully paid orders</strong> that are not marked "
"as paid, probably because no quota was left at the time their payment "
"arrived. You should review the cases and consider either refunding the "
"customer or creating more space."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid "Show affected orders"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid ""
"Orders in this event could not be <strong>synced to an external system</"
"strong> as configured."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid "Show sync problems"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/delete.html
msgid ""
"This operation will destroy your event including all configuration, "
@@ -18198,6 +18007,69 @@ msgstr ""
msgid "Create QR code"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid ""
"This event contains <strong>overpaid orders</strong>, for example due to "
"duplicate payment attempts. You should review the cases and consider "
"refunding the overpaid amount to the user."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid "Show overpaid orders"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid ""
"This event contains <strong>pending refunds</strong> that you should take "
"care of."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid "Show pending refunds"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid ""
"This event contains <strong>requested cancellations</strong> that you should "
"take care of."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid "Show orders requesting cancellation"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid ""
"This event contains <strong>pending approvals</strong> that you should take "
"care of."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid "Show orders pending approval"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid ""
"This event contains <strong>fully paid orders</strong> that are not marked "
"as paid, probably because no quota was left at the time their payment "
"arrived. You should review the cases and consider either refunding the "
"customer or creating more space."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid "Show affected orders"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid ""
"Orders in this event could not be <strong>synced to an external system</"
"strong> as configured."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid "Show sync problems"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
#: pretix/control/templates/pretixcontrol/order/index.html
msgid "Update comment"
@@ -18372,6 +18244,44 @@ msgstr ""
msgid "Enable test mode"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
msgid "All actions"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/logs.html
msgid "Team actions"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/logs.html
msgid "Customer actions"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/event/logs_embed.html
#: pretix/control/templates/pretixcontrol/includes/logs.html
#: pretix/control/templates/pretixcontrol/organizers/device_logs.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
msgid "Personal data was cleared from this log entry."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/event/logs_embed.html
#: pretix/control/templates/pretixcontrol/includes/logs.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
msgid "This change was performed by a pretix administrator."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/event/logs_embed.html
#: pretix/control/templates/pretixcontrol/includes/logs.html
#: pretix/control/templates/pretixcontrol/order/index.html
#: pretix/control/templates/pretixcontrol/organizers/device_logs.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
#: pretix/control/templates/pretixcontrol/search/payments.html
msgid "Inspect"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/organizers/device_logs.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
@@ -19270,20 +19180,6 @@ msgstr ""
msgid "More quotas"
msgstr ""
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/views/dashboards.py
msgid "Shop disabled"
msgstr ""
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/subevents/detail.html
#: pretix/control/templates/pretixcontrol/subevents/index.html
#: pretix/control/views/dashboards.py
msgid "On sale"
msgstr ""
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
msgid "Open event dashboard"
@@ -19294,10 +19190,6 @@ msgctxt "typography"
msgid "The quick brown fox jumps over the lazy dog."
msgstr ""
#: pretix/control/templates/pretixcontrol/fragment_log_filter_form.html
msgid "Specific object selected"
msgstr ""
#: pretix/control/templates/pretixcontrol/fragment_quota_box.html
#: pretix/control/templates/pretixcontrol/fragment_quota_box_paid.html
msgid "Quota:"
@@ -20312,7 +20204,6 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/items/quota_bulk_edit.html
#: pretix/control/templates/pretixcontrol/organizers/device_bulk_edit.html
#: pretix/control/templates/pretixcontrol/subevents/bulk_edit.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk_edit.html
#, python-format
msgid "%(number)s selected"
msgstr ""
@@ -20399,7 +20290,6 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/items/quotas.html
#: pretix/control/templates/pretixcontrol/organizers/devices.html
#: pretix/control/templates/pretixcontrol/subevents/index.html
#: pretix/control/templates/pretixcontrol/vouchers/index.html
msgid "Edit selected"
msgstr ""
@@ -20696,13 +20586,6 @@ msgid ""
"the customer account."
msgstr ""
#: pretix/control/templates/pretixcontrol/order/change.html
#: pretix/control/views/orders.py
msgid ""
"Ticket secrets of order positions that have been used to issue a gift card "
"can not be changed. Only the link will be changed in this case."
msgstr ""
#: pretix/control/templates/pretixcontrol/order/change.html
msgid ""
"Removing or splitting this position will also remove or split all add-ons to "
@@ -21115,6 +20998,11 @@ msgstr ""
msgid "Create a refund"
msgstr ""
#: pretix/control/templates/pretixcontrol/order/index.html
#: pretix/control/templates/pretixcontrol/orders/refunds.html
msgid "Source"
msgstr ""
#: pretix/control/templates/pretixcontrol/order/index.html
msgid "Cancel transfer"
msgstr ""
@@ -22191,7 +22079,6 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/organizers/device_bulk_edit.html
#: pretix/control/templates/pretixcontrol/organizers/device_edit.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk_edit.html
#: pretix/control/templates/pretixcontrol/vouchers/detail.html
msgid "Advanced settings"
msgstr ""
@@ -24348,13 +24235,11 @@ msgid "Copy codes"
msgstr ""
#: pretix/control/templates/pretixcontrol/vouchers/bulk.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk_edit.html
#: pretix/control/templates/pretixcontrol/vouchers/detail.html
msgid "Voucher details"
msgstr ""
#: pretix/control/templates/pretixcontrol/vouchers/bulk.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk_edit.html
#: pretix/control/templates/pretixcontrol/vouchers/detail.html
msgid ""
"If you choose \"any product\" for a specific quota and choose to reserve "
@@ -24362,10 +24247,6 @@ msgid ""
"voucher holder if another quota associated with the product is sold out!"
msgstr ""
#: pretix/control/templates/pretixcontrol/vouchers/bulk_edit.html
msgid "Change multiple vouchers"
msgstr ""
#: pretix/control/templates/pretixcontrol/vouchers/delete.html
#: pretix/control/templates/pretixcontrol/vouchers/detail.html
msgid "Delete voucher"
@@ -24705,8 +24586,7 @@ msgstr ""
#, python-brace-format
msgid ""
"You cannot accept the invitation for \"{}\" as you already are part of this "
"team. If you want to add a different user or create a new account, log out "
"and click the invitation link again."
"team."
msgstr ""
#: pretix/control/views/auth.py
@@ -25309,30 +25189,6 @@ msgid ""
"record."
msgstr ""
#: pretix/control/views/mailsetup.py
msgid ""
"We could not find a CNAME record pointing to our DKIM key for domain you are "
"trying to use. This means that there is a very high change most of the "
"emails will be rejected or marked as spam. We strongly recommend setting up "
"DKIM through a CNAME record. You can do so through the DNS settings at the "
"provider you registered your domain with."
msgstr ""
#: pretix/control/views/mailsetup.py
msgid ""
"We found a CNAME record for a DKIM key, but it is not pointing to the right "
"location. This means that there is a very high chance most of the emails "
"will be rejected or marked as spam. You should update the DNS settings of "
"your domain."
msgstr ""
#: pretix/control/views/mailsetup.py
msgid ""
"We did not find DMARC record for your domain. This means that there is a "
"very high chance most of the emails will be rejected or marked as spam. You "
"should update the DNS settings of your domain."
msgstr ""
#: pretix/control/views/mailsetup.py
msgid "The verification code was incorrect, please try again."
msgstr ""
@@ -26392,7 +26248,6 @@ msgid "Macao"
msgstr ""
#: pretix/helpers/daterange.py
#: pretix/presale/templates/pretixpresale/event/fragment_subevent_list.html
#: pretix/presale/templates/pretixpresale/fragment_calendar.html
#: pretix/presale/templates/pretixpresale/fragment_week_calendar.html
#: pretix/presale/templates/pretixpresale/organizers/index.html
@@ -27580,6 +27435,11 @@ msgstr ""
msgid "PayPal account"
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
#, python-brace-format
msgid "<a target=\"_blank\" rel=\"noopener\" href=\"{docs_url}\">{text}</a>"
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid "Click here for a tutorial on how to obtain the required keys"
msgstr ""
@@ -28214,13 +28074,8 @@ msgstr ""
#: pretix/plugins/returnurl/views.py
msgid ""
"Redirection will only be allowed to URLs that start with one of these "
"prefixes. Enter one allowed URL prefix per line. URL prefixes must include a "
"slash after the hostname."
msgstr ""
#: pretix/plugins/returnurl/views.py
msgid ""
"All values must be URLs that include at last one slash after the hostname."
"prefixes. Enter one or more allowed URL prefix per line. URL prefixes must "
"include a slash after the hostname."
msgstr ""
#: pretix/plugins/sendmail/apps.py
+236 -404
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-30 13:52+0000\n"
"POT-Creation-Date: 2026-07-07 09:30+0000\n"
"PO-Revision-Date: 2026-06-25 14:00+0000\n"
"Last-Translator: Kim Lozano <joaquim.lozano@upc.edu>\n"
"Language-Team: Catalan <https://translate.pretix.eu/projects/pretix/pretix/"
@@ -19,6 +19,38 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 2026.6.1\n"
#: htmlcov/d_daa1541d0cbf5e2b_dashboards_py.html
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/views/dashboards.py
msgid "Shop disabled"
msgstr "Botiga desactivada"
#: htmlcov/d_daa1541d0cbf5e2b_dashboards_py.html pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/subevents/detail.html
#: pretix/control/templates/pretixcontrol/subevents/index.html
msgid "Presale over"
msgstr "S'ha acabat la prevenda"
#: htmlcov/d_daa1541d0cbf5e2b_dashboards_py.html pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/subevents/detail.html
#: pretix/control/templates/pretixcontrol/subevents/index.html
msgid "Presale not started"
msgstr "No ha començat la prevenda"
#: htmlcov/d_daa1541d0cbf5e2b_dashboards_py.html
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/subevents/detail.html
#: pretix/control/templates/pretixcontrol/subevents/index.html
#: pretix/control/views/dashboards.py
msgid "On sale"
msgstr "En venda"
#: pretix/_base_settings.py
msgid "English"
msgstr "Anglès"
@@ -1342,24 +1374,6 @@ msgstr "Compte de Stripe"
msgid "Download a spreadsheet of all currently registered customer accounts."
msgstr ""
#: pretix/base/exporters/customers.py pretix/base/permissions.py
#: pretix/control/navigation.py
#: pretix/control/templates/pretixcontrol/organizers/customers.html
#, fuzzy
#| msgctxt "refund_source"
#| msgid "Customer"
msgid "Customers"
msgstr "Client"
#: pretix/base/exporters/customers.py pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/organizers/customer.html
#: pretix/presale/templates/pretixpresale/organizers/customer_memberships.html
#: pretix/presale/views/customer.py
#, fuzzy
#| msgid "Members"
msgid "Memberships"
msgstr "Membres"
#: pretix/base/exporters/customers.py pretix/base/models/customers.py
#: pretix/control/templates/pretixcontrol/organizers/customer.html
#: pretix/control/templates/pretixcontrol/organizers/customers.html
@@ -1499,74 +1513,6 @@ msgstr "Si"
msgid "No"
msgstr "No"
#: pretix/base/exporters/customers.py pretix/base/exporters/orderlist.py
#: pretix/base/models/memberships.py pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/event/live.html
msgid "Test mode"
msgstr "Mode de prova"
#: pretix/base/exporters/customers.py pretix/base/models/memberships.py
#: pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/orders/fragment_order_status.html
#: pretix/control/templates/pretixcontrol/orders/overview.html
#: pretix/control/templates/pretixcontrol/organizers/customer_membership.html
#: pretix/plugins/reports/exporters.py
#: pretix/presale/templates/pretixpresale/event/fragment_order_status.html
#: pretix/presale/templates/pretixpresale/organizers/customer_membership.html
#: pretix/presale/templates/pretixpresale/organizers/customer_memberships.html
msgid "Canceled"
msgstr "Cancel·lat"
#: pretix/base/exporters/customers.py pretix/base/models/memberships.py
#: pretix/control/templates/pretixcontrol/organizers/customer.html
#: pretix/presale/templates/pretixpresale/organizers/customer_membership.html
#, fuzzy
#| msgid "Members"
msgid "Membership type"
msgstr "Membres"
#: pretix/base/exporters/customers.py
#, fuzzy
#| msgid "Purchased"
msgid "Purchase ticket"
msgstr "Comprat"
#: pretix/base/exporters/customers.py pretix/base/exporters/orderlist.py
#: pretix/base/exporters/waitinglist.py pretix/base/forms/questions.py
#: pretix/base/models/memberships.py pretix/control/forms/rrule.py
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/order/index.html
#: pretix/control/templates/pretixcontrol/orders/refunds.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/search/payments.html
#: pretix/control/templates/pretixcontrol/user/staff_session_edit.html
#: pretix/control/templates/pretixcontrol/user/staff_session_list.html
#: pretix/plugins/checkinlists/exporters.py
msgid "Start date"
msgstr "Data d'inici"
#: pretix/base/exporters/customers.py
#, fuzzy
#| msgid "Date"
msgid "Start time"
msgstr "Data"
#: pretix/base/exporters/customers.py pretix/base/exporters/orderlist.py
#: pretix/base/exporters/waitinglist.py pretix/base/models/memberships.py
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/user/staff_session_edit.html
#: pretix/control/templates/pretixcontrol/user/staff_session_list.html
#: pretix/plugins/checkinlists/exporters.py
msgid "End date"
msgstr "Data de finalització"
#: pretix/base/exporters/customers.py
#, fuzzy
#| msgid "End: %(time)s"
msgid "End time"
msgstr "Final: %(time)s"
#: pretix/base/exporters/dekodi.py pretix/base/exporters/invoices.py
#, fuzzy
#| msgid "Invoices"
@@ -2444,6 +2390,30 @@ msgstr "cancel·lat"
msgid "Position ID"
msgstr "Identificador de la posició"
#: pretix/base/exporters/orderlist.py pretix/base/exporters/waitinglist.py
#: pretix/base/forms/questions.py pretix/base/models/memberships.py
#: pretix/control/forms/rrule.py
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/order/index.html
#: pretix/control/templates/pretixcontrol/orders/refunds.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/search/payments.html
#: pretix/control/templates/pretixcontrol/user/staff_session_edit.html
#: pretix/control/templates/pretixcontrol/user/staff_session_list.html
#: pretix/plugins/checkinlists/exporters.py
msgid "Start date"
msgstr "Data d'inici"
#: pretix/base/exporters/orderlist.py pretix/base/exporters/waitinglist.py
#: pretix/base/models/memberships.py
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/user/staff_session_edit.html
#: pretix/control/templates/pretixcontrol/user/staff_session_list.html
#: pretix/plugins/checkinlists/exporters.py
msgid "End date"
msgstr "Data de finalització"
#: pretix/base/exporters/orderlist.py pretix/base/exporters/waitinglist.py
#: pretix/base/modelimport_orders.py pretix/base/modelimport_vouchers.py
#: pretix/base/models/items.py pretix/base/models/vouchers.py
@@ -2884,6 +2854,12 @@ msgstr ""
msgid "Gift card code"
msgstr "Codi del val regal"
#: pretix/base/exporters/orderlist.py pretix/base/models/memberships.py
#: pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/event/live.html
msgid "Test mode"
msgstr "Mode de prova"
#: pretix/base/exporters/orderlist.py pretix/base/models/organizer.py
#: pretix/control/forms/event.py pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/email_setup.html
@@ -2997,7 +2973,7 @@ msgstr "Expirat i amb valor"
#: pretix/control/templates/pretixcontrol/orders/overview.html
#: pretix/control/templates/pretixcontrol/organizers/customer.html
#: pretix/control/templates/pretixcontrol/organizers/giftcards.html
#: pretix/plugins/reports/exporters.py pretix/plugins/sendmail/forms.py
#: pretix/plugins/reports/exporters.py
#: pretix/presale/templates/pretixpresale/event/fragment_order_status.html
#: pretix/presale/templates/pretixpresale/organizers/customer_giftcards.html
msgid "Expired"
@@ -3183,7 +3159,7 @@ msgid "This combination of credentials is not known to our system."
msgstr "El sistema no reconeix aquesta combinació de credencials."
#: pretix/base/forms/auth.py pretix/base/forms/user.py
#: pretix/control/views/user.py pretix/presale/forms/customer.py
#: pretix/presale/forms/customer.py
msgid "For security reasons, please wait 5 minutes before you try again."
msgstr ""
"Per raons de seguretat, si us plau espereu 5 minuts abans de tornar-ho a "
@@ -4210,7 +4186,6 @@ msgstr "Permet traspassar la quota"
#: pretix/base/modelimport_vouchers.py pretix/base/models/vouchers.py
#: pretix/control/templates/pretixcontrol/vouchers/bulk.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk_edit.html
#: pretix/control/templates/pretixcontrol/vouchers/detail.html
#: pretix/control/views/vouchers.py
msgid "Price effect"
@@ -4934,8 +4909,8 @@ msgstr ""
#: pretix/base/models/event.py
msgid ""
"This will be used to let users know if the event is in a different timezone, "
"and to let us calculate the local time of a user."
"This will be used to let users know if the event is in a different timezone "
"and lets us calculate users local times."
msgstr ""
#: pretix/base/models/event.py pretix/base/models/organizer.py
@@ -6473,6 +6448,25 @@ msgstr ""
msgid "Number of times this membership can be used in a purchase."
msgstr "Número de vegades que es pot utilitzar aquest val."
#: pretix/base/models/memberships.py pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/orders/fragment_order_status.html
#: pretix/control/templates/pretixcontrol/orders/overview.html
#: pretix/control/templates/pretixcontrol/organizers/customer_membership.html
#: pretix/plugins/reports/exporters.py
#: pretix/presale/templates/pretixpresale/event/fragment_order_status.html
#: pretix/presale/templates/pretixpresale/organizers/customer_membership.html
#: pretix/presale/templates/pretixpresale/organizers/customer_memberships.html
msgid "Canceled"
msgstr "Cancel·lat"
#: pretix/base/models/memberships.py
#: pretix/control/templates/pretixcontrol/organizers/customer.html
#: pretix/presale/templates/pretixpresale/organizers/customer_membership.html
#, fuzzy
#| msgid "Members"
msgid "Membership type"
msgstr "Membres"
#: pretix/base/models/orders.py
msgid "pending"
msgstr "pendent"
@@ -7333,7 +7327,7 @@ msgstr "Aquesta variació no pertany a aquest producte."
msgid "It is currently not possible to create vouchers for add-on products."
msgstr "Actualment no es poden crear vals per a complements de productes."
#: pretix/base/models/vouchers.py pretix/control/forms/vouchers.py
#: pretix/base/models/vouchers.py
msgid ""
"You need to select a specific product or quota if this voucher should "
"reserve tickets."
@@ -7361,7 +7355,7 @@ msgid ""
msgstr ""
"El número màxim per comanda no pot ser menor que el número mínim per comanda."
#: pretix/base/models/vouchers.py pretix/control/forms/vouchers.py
#: pretix/base/models/vouchers.py
msgid ""
"If you want this voucher to block quota, you need to select a specific date."
msgstr ""
@@ -7905,12 +7899,6 @@ msgstr ""
msgid "This gift card was used in the meantime. Please try again."
msgstr "Aquesta targeta regal ja s'ha fet servir. Si us plau torneu a provar."
#: pretix/base/payment.py
msgid ""
"This payment provider exists for historical purposes only and is no longer "
"usable."
msgstr ""
#: pretix/base/pdf.py
msgid "Ticket code (barcode content)"
msgstr "Codi de tiquet (contingut del codi de barres)"
@@ -8561,6 +8549,14 @@ msgid ""
"permissions."
msgstr ""
#: pretix/base/permissions.py pretix/control/navigation.py
#: pretix/control/templates/pretixcontrol/organizers/customers.html
#, fuzzy
#| msgctxt "refund_source"
#| msgid "Customer"
msgid "Customers"
msgstr "Client"
#: pretix/base/permissions.py pretix/control/navigation.py
msgid "Devices"
msgstr ""
@@ -9953,14 +9949,6 @@ msgid ""
"card."
msgstr ""
#: pretix/base/services/orders.py
#, fuzzy
#| msgid "You cannot select a quota that belongs to a different event."
msgid ""
"You cannot change the ticket secret of a position that has been used to "
"issue a gift card."
msgstr "No podeu seleccionar una quota que pertany a un esdeveniment diferent."
#: pretix/base/services/orders.py
#, python-brace-format
msgid ""
@@ -11834,13 +11822,13 @@ msgid "We'll show this publicly to allow attendees to contact you."
msgstr ""
"Això es mostrarà públicament per permetre que els assistents us contactin."
#: pretix/base/settings.py
#: pretix/base/settings.py pretix/control/forms/event.py
#, fuzzy
#| msgid "Contact address"
msgid "Contact URL"
msgstr "Adreça de contacte"
#: pretix/base/settings.py
#: pretix/base/settings.py pretix/control/forms/event.py
msgid ""
"If you set this, the footer contact link will point here instead of using "
"the email address above. Please note that you still need to add a contact "
@@ -13876,7 +13864,6 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/organizers/customer.html
#: pretix/control/templates/pretixcontrol/organizers/customer_membership.html
#: pretix/control/templates/pretixcontrol/organizers/customers.html
#: pretix/control/templates/pretixcontrol/organizers/devices.html
#: pretix/control/templates/pretixcontrol/organizers/giftcard.html
#: pretix/control/templates/pretixcontrol/organizers/giftcards.html
#: pretix/control/templates/pretixcontrol/organizers/reusable_media.html
@@ -15316,7 +15303,7 @@ msgstr "Totes les comandes"
msgid "Valid orders"
msgstr "Comandes pagades"
#: pretix/control/forms/filter.py pretix/plugins/sendmail/forms.py
#: pretix/control/forms/filter.py
msgid "Paid (or canceled with paid fee)"
msgstr "Paga (o cancel·lat amb tarifa de pagament)"
@@ -15345,7 +15332,7 @@ msgstr "Pendent o pagat"
msgid "Cancellations"
msgstr "Cancel·lació"
#: pretix/control/forms/filter.py pretix/plugins/sendmail/forms.py
#: pretix/control/forms/filter.py
#, fuzzy
#| msgid "Canceled (paid fee)"
msgid "Canceled (fully)"
@@ -15559,22 +15546,6 @@ msgstr "La tenda està activa i la pre-venda en marxa"
msgid "Inactive"
msgstr "Inactiu"
#: pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/subevents/detail.html
#: pretix/control/templates/pretixcontrol/subevents/index.html
msgid "Presale not started"
msgstr "No ha començat la prevenda"
#: pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/subevents/detail.html
#: pretix/control/templates/pretixcontrol/subevents/index.html
msgid "Presale over"
msgstr "S'ha acabat la prevenda"
#: pretix/control/forms/filter.py
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/import_form.html
#, fuzzy
@@ -15624,6 +15595,15 @@ msgstr "Inactiu"
msgid "not yet activated"
msgstr "Inactiu"
#: pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/organizers/customer.html
#: pretix/presale/templates/pretixpresale/organizers/customer_memberships.html
#: pretix/presale/views/customer.py
#, fuzzy
#| msgid "Members"
msgid "Memberships"
msgstr "Membres"
#: pretix/control/forms/filter.py
#, fuzzy
#| msgid "Event end"
@@ -15897,42 +15877,6 @@ msgstr "Revocar l'accés"
msgid "Search email address or subject"
msgstr "Requereix adreces de correu per tiquet"
#: pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/order/index.html
#: pretix/control/templates/pretixcontrol/orders/refunds.html
msgid "Source"
msgstr ""
#: pretix/control/forms/filter.py
#, fuzzy
#| msgid "All orders"
msgid "All sources"
msgstr "Totes les comandes"
#: pretix/control/forms/filter.py
msgid "Team actions"
msgstr ""
#: pretix/control/forms/filter.py
msgid "Customer actions"
msgstr ""
#: pretix/control/forms/filter.py
#, fuzzy
#| msgid "Device name"
msgid "Device actions"
msgstr "Nom del dispositiu"
#: pretix/control/forms/filter.py
#, fuzzy
#| msgid "Order details"
msgid "User email"
msgstr "Detalls de la comanda"
#: pretix/control/forms/filter.py pretix/control/navigation.py
msgid "All users"
msgstr ""
#: pretix/control/forms/global_settings.py
msgid "Additional footer text"
msgstr ""
@@ -17262,7 +17206,6 @@ msgstr "Opcional"
#: pretix/control/forms/renderers.py
#: pretix/control/templates/pretixcontrol/organizers/device_bulk_edit.html
#: pretix/control/templates/pretixcontrol/subevents/bulk_edit.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk_edit.html
#, fuzzy
#| msgid "Save changes"
msgctxt "form_bulk"
@@ -17384,65 +17327,6 @@ msgid ""
"should show them."
msgstr ""
#: pretix/control/forms/vouchers.py
#, python-format
msgid ""
"You cannot reduce the maximum number of redemptions to %(max_usages)s, "
"because at least one of the selected vouchers has already been redeemed "
"%(max_redeemed)s times."
msgstr ""
#: pretix/control/forms/vouchers.py
#, fuzzy
#| msgid ""
#| "You cannot create a voucher that blocks quota as the selected product or "
#| "quota is currently sold out or completely reserved."
msgid ""
"You cannot create a voucher that allows selection of a quota but has no date "
"selected."
msgstr ""
"No podeu crear un val que bloca la quota ja que el producte o quota "
"seleccionats s'han venut o reservat completament."
#: pretix/control/forms/vouchers.py
#, fuzzy
#| msgid "The selected product does not allow to select a seat."
msgid "The selected quota does not match the selected subevent."
msgstr "El producte seleccionat no permet triar un seient."
#: pretix/control/forms/vouchers.py
#, fuzzy
#| msgid ""
#| "There is not enough quota available on quota \"{}\" to perform the "
#| "operation."
msgid "There is no sufficient quota available to perform this change."
msgstr "No hi ha prou quota disponible a \"{}\" per realitzar l'operació."
#: pretix/control/forms/vouchers.py
msgid ""
"Changing the maximum number of usages in bulk is not supported if any of the "
"selected vouchers is assigned a seat."
msgstr ""
#: pretix/control/forms/vouchers.py
msgctxt "subevent"
msgid ""
"Changing the date in bulk is not supported if any of the selected vouchers "
"is assigned a seat."
msgstr ""
#: pretix/control/forms/vouchers.py
msgid ""
"Changing the product to a quota is not supported if any of the selected "
"vouchers is assigned a seat."
msgstr ""
#: pretix/control/forms/vouchers.py
msgid ""
"This change cannot be completed because not all assigned seats of the "
"vouchers are still available"
msgstr ""
#: pretix/control/forms/vouchers.py
msgid "Codes"
msgstr ""
@@ -19390,6 +19274,10 @@ msgstr ""
msgid "Account history"
msgstr ""
#: pretix/control/navigation.py
msgid "All users"
msgstr ""
#: pretix/control/navigation.py
#: pretix/control/templates/pretixcontrol/user/staff_session_list.html
msgid "Admin sessions"
@@ -19675,7 +19563,6 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/users/create.html
#: pretix/control/templates/pretixcontrol/users/form.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk_edit.html
#: pretix/control/templates/pretixcontrol/vouchers/detail.html
#: pretix/control/templates/pretixcontrol/waitinglist/edit.html
#: pretix/plugins/autocheckin/templates/pretixplugins/autocheckin/add.html
@@ -20129,8 +20016,8 @@ msgstr "Esborrar"
#: pretix/control/templates/pretixcontrol/checkin/checkins.html
#: pretix/control/templates/pretixcontrol/checkin/index.html
#: pretix/control/templates/pretixcontrol/checkin/lists.html
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/fragment_log_filter_form.html
#: pretix/control/templates/pretixcontrol/items/question.html
#: pretix/control/templates/pretixcontrol/items/quotas.html
#: pretix/control/templates/pretixcontrol/orders/index.html
@@ -20141,6 +20028,7 @@ msgstr "Esborrar"
#: pretix/control/templates/pretixcontrol/organizers/devices.html
#: pretix/control/templates/pretixcontrol/organizers/giftcards.html
#: pretix/control/templates/pretixcontrol/organizers/index.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
#: pretix/control/templates/pretixcontrol/organizers/outgoing_mails.html
#: pretix/control/templates/pretixcontrol/organizers/reusable_media.html
#: pretix/control/templates/pretixcontrol/organizers/teams.html
@@ -20292,7 +20180,6 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/organizers/devices.html
#: pretix/control/templates/pretixcontrol/organizers/outgoing_mails.html
#: pretix/control/templates/pretixcontrol/subevents/index.html
#: pretix/control/templates/pretixcontrol/vouchers/index.html
#: pretix/control/templates/pretixcontrol/waitinglist/index.html
msgid "Select all results on other pages as well"
msgstr ""
@@ -20936,22 +20823,6 @@ msgstr ""
msgid "We found an SPF record on your domain that includes this system. Great!"
msgstr ""
#: pretix/control/templates/pretixcontrol/email_setup_simple.html
msgid "Your new DKIM record should be set up as a CNAME record like this:"
msgstr ""
#: pretix/control/templates/pretixcontrol/email_setup_simple.html
msgid "We found a DKIM record on your domain for this system. Great!"
msgstr ""
#: pretix/control/templates/pretixcontrol/email_setup_simple.html
msgid "Your new DMARC record could look like this:"
msgstr ""
#: pretix/control/templates/pretixcontrol/email_setup_simple.html
msgid "We found a DMARC record on your domain for this system. Great!"
msgstr ""
#: pretix/control/templates/pretixcontrol/email_setup_simple.html
#, fuzzy
#| msgid "Verification failed"
@@ -21126,94 +20997,6 @@ msgid ""
"undeletable data, such as orders not performed in test mode."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_logs.html
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/includes/logs.html
#: pretix/control/templates/pretixcontrol/organizers/device_logs.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
msgid "Personal data was cleared from this log entry."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_logs.html
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/includes/logs.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
msgid "This change was performed by a pretix administrator."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_logs.html
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/includes/logs.html
#: pretix/control/templates/pretixcontrol/order/index.html
#: pretix/control/templates/pretixcontrol/organizers/device_logs.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
#: pretix/control/templates/pretixcontrol/search/payments.html
msgid "Inspect"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid ""
"This event contains <strong>overpaid orders</strong>, for example due to "
"duplicate payment attempts. You should review the cases and consider "
"refunding the overpaid amount to the user."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid "Show overpaid orders"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid ""
"This event contains <strong>pending refunds</strong> that you should take "
"care of."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid "Show pending refunds"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid ""
"This event contains <strong>requested cancellations</strong> that you should "
"take care of."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid "Show orders requesting cancellation"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid ""
"This event contains <strong>pending approvals</strong> that you should take "
"care of."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid "Show orders pending approval"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid ""
"This event contains <strong>fully paid orders</strong> that are not marked "
"as paid, probably because no quota was left at the time their payment "
"arrived. You should review the cases and consider either refunding the "
"customer or creating more space."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid "Show affected orders"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid ""
"Orders in this event could not be <strong>synced to an external system</"
"strong> as configured."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid "Show sync problems"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/delete.html
msgid ""
"This operation will destroy your event including all configuration, "
@@ -21332,6 +21115,69 @@ msgstr "URL de sistema:"
msgid "Create QR code"
msgstr "Codi de comanda"
#: pretix/control/templates/pretixcontrol/event/index.html
msgid ""
"This event contains <strong>overpaid orders</strong>, for example due to "
"duplicate payment attempts. You should review the cases and consider "
"refunding the overpaid amount to the user."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid "Show overpaid orders"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid ""
"This event contains <strong>pending refunds</strong> that you should take "
"care of."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid "Show pending refunds"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid ""
"This event contains <strong>requested cancellations</strong> that you should "
"take care of."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid "Show orders requesting cancellation"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid ""
"This event contains <strong>pending approvals</strong> that you should take "
"care of."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid "Show orders pending approval"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid ""
"This event contains <strong>fully paid orders</strong> that are not marked "
"as paid, probably because no quota was left at the time their payment "
"arrived. You should review the cases and consider either refunding the "
"customer or creating more space."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid "Show affected orders"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid ""
"Orders in this event could not be <strong>synced to an external system</"
"strong> as configured."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid "Show sync problems"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
#: pretix/control/templates/pretixcontrol/order/index.html
msgid "Update comment"
@@ -21523,6 +21369,44 @@ msgstr ""
msgid "Enable test mode"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
msgid "All actions"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/logs.html
msgid "Team actions"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/logs.html
msgid "Customer actions"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/event/logs_embed.html
#: pretix/control/templates/pretixcontrol/includes/logs.html
#: pretix/control/templates/pretixcontrol/organizers/device_logs.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
msgid "Personal data was cleared from this log entry."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/event/logs_embed.html
#: pretix/control/templates/pretixcontrol/includes/logs.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
msgid "This change was performed by a pretix administrator."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/event/logs_embed.html
#: pretix/control/templates/pretixcontrol/includes/logs.html
#: pretix/control/templates/pretixcontrol/order/index.html
#: pretix/control/templates/pretixcontrol/organizers/device_logs.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
#: pretix/control/templates/pretixcontrol/search/payments.html
msgid "Inspect"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/organizers/device_logs.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
@@ -22535,20 +22419,6 @@ msgstr ""
msgid "More quotas"
msgstr ""
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/views/dashboards.py
msgid "Shop disabled"
msgstr "Botiga desactivada"
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/subevents/detail.html
#: pretix/control/templates/pretixcontrol/subevents/index.html
#: pretix/control/views/dashboards.py
msgid "On sale"
msgstr "En venda"
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
msgid "Open event dashboard"
@@ -22559,12 +22429,6 @@ msgctxt "typography"
msgid "The quick brown fox jumps over the lazy dog."
msgstr ""
#: pretix/control/templates/pretixcontrol/fragment_log_filter_form.html
#, fuzzy
#| msgid "Specific seat"
msgid "Specific object selected"
msgstr "Seient específic"
#: pretix/control/templates/pretixcontrol/fragment_quota_box.html
#: pretix/control/templates/pretixcontrol/fragment_quota_box_paid.html
msgid "Quota:"
@@ -23682,7 +23546,6 @@ msgstr "Pot canviar les comandes"
#: pretix/control/templates/pretixcontrol/items/quota_bulk_edit.html
#: pretix/control/templates/pretixcontrol/organizers/device_bulk_edit.html
#: pretix/control/templates/pretixcontrol/subevents/bulk_edit.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk_edit.html
#, python-format
msgid "%(number)s selected"
msgstr ""
@@ -23773,7 +23636,6 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/items/quotas.html
#: pretix/control/templates/pretixcontrol/organizers/devices.html
#: pretix/control/templates/pretixcontrol/subevents/index.html
#: pretix/control/templates/pretixcontrol/vouchers/index.html
msgid "Edit selected"
msgstr ""
@@ -24079,13 +23941,6 @@ msgid ""
"the customer account."
msgstr ""
#: pretix/control/templates/pretixcontrol/order/change.html
#: pretix/control/views/orders.py
msgid ""
"Ticket secrets of order positions that have been used to issue a gift card "
"can not be changed. Only the link will be changed in this case."
msgstr ""
#: pretix/control/templates/pretixcontrol/order/change.html
#, fuzzy
#| msgid ""
@@ -24546,6 +24401,11 @@ msgstr ""
msgid "Create a refund"
msgstr ""
#: pretix/control/templates/pretixcontrol/order/index.html
#: pretix/control/templates/pretixcontrol/orders/refunds.html
msgid "Source"
msgstr ""
#: pretix/control/templates/pretixcontrol/order/index.html
msgid "Cancel transfer"
msgstr ""
@@ -25770,7 +25630,6 @@ msgstr "Pot canviar les comandes"
#: pretix/control/templates/pretixcontrol/organizers/device_bulk_edit.html
#: pretix/control/templates/pretixcontrol/organizers/device_edit.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk_edit.html
#: pretix/control/templates/pretixcontrol/vouchers/detail.html
msgid "Advanced settings"
msgstr "Configuració avançada"
@@ -28139,13 +27998,11 @@ msgid "Copy codes"
msgstr "Copiar codis"
#: pretix/control/templates/pretixcontrol/vouchers/bulk.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk_edit.html
#: pretix/control/templates/pretixcontrol/vouchers/detail.html
msgid "Voucher details"
msgstr "Detalls del val"
#: pretix/control/templates/pretixcontrol/vouchers/bulk.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk_edit.html
#: pretix/control/templates/pretixcontrol/vouchers/detail.html
msgid ""
"If you choose \"any product\" for a specific quota and choose to reserve "
@@ -28153,12 +28010,6 @@ msgid ""
"voucher holder if another quota associated with the product is sold out!"
msgstr ""
#: pretix/control/templates/pretixcontrol/vouchers/bulk_edit.html
#, fuzzy
#| msgid "Create multiple vouchers"
msgid "Change multiple vouchers"
msgstr "Crear múltiples vals"
#: pretix/control/templates/pretixcontrol/vouchers/delete.html
#: pretix/control/templates/pretixcontrol/vouchers/detail.html
msgid "Delete voucher"
@@ -28522,8 +28373,7 @@ msgstr ""
#, python-brace-format
msgid ""
"You cannot accept the invitation for \"{}\" as you already are part of this "
"team. If you want to add a different user or create a new account, log out "
"and click the invitation link again."
"team."
msgstr ""
#: pretix/control/views/auth.py
@@ -29163,30 +29013,6 @@ msgid ""
"record."
msgstr ""
#: pretix/control/views/mailsetup.py
msgid ""
"We could not find a CNAME record pointing to our DKIM key for domain you are "
"trying to use. This means that there is a very high change most of the "
"emails will be rejected or marked as spam. We strongly recommend setting up "
"DKIM through a CNAME record. You can do so through the DNS settings at the "
"provider you registered your domain with."
msgstr ""
#: pretix/control/views/mailsetup.py
msgid ""
"We found a CNAME record for a DKIM key, but it is not pointing to the right "
"location. This means that there is a very high chance most of the emails "
"will be rejected or marked as spam. You should update the DNS settings of "
"your domain."
msgstr ""
#: pretix/control/views/mailsetup.py
msgid ""
"We did not find DMARC record for your domain. This means that there is a "
"very high chance most of the emails will be rejected or marked as spam. You "
"should update the DNS settings of your domain."
msgstr ""
#: pretix/control/views/mailsetup.py
#, fuzzy
#| msgid "This gift card was used in the meantime. Please try again."
@@ -30374,7 +30200,6 @@ msgid "Macao"
msgstr ""
#: pretix/helpers/daterange.py
#: pretix/presale/templates/pretixpresale/event/fragment_subevent_list.html
#: pretix/presale/templates/pretixpresale/fragment_calendar.html
#: pretix/presale/templates/pretixpresale/fragment_week_calendar.html
#: pretix/presale/templates/pretixpresale/organizers/index.html
@@ -31714,6 +31539,11 @@ msgstr ""
msgid "PayPal account"
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
#, python-brace-format
msgid "<a target=\"_blank\" rel=\"noopener\" href=\"{docs_url}\">{text}</a>"
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid "Click here for a tutorial on how to obtain the required keys"
msgstr ""
@@ -32439,13 +32269,8 @@ msgstr "URL base de la redirecció"
#: pretix/plugins/returnurl/views.py
msgid ""
"Redirection will only be allowed to URLs that start with one of these "
"prefixes. Enter one allowed URL prefix per line. URL prefixes must include a "
"slash after the hostname."
msgstr ""
#: pretix/plugins/returnurl/views.py
msgid ""
"All values must be URLs that include at last one slash after the hostname."
"prefixes. Enter one or more allowed URL prefix per line. URL prefixes must "
"include a slash after the hostname."
msgstr ""
#: pretix/plugins/sendmail/apps.py
@@ -38462,6 +38287,13 @@ msgstr "Kosovo"
#~ msgid "Full access"
#~ msgstr "Nom complet"
#, fuzzy
#~| msgid "You cannot select a quota that belongs to a different event."
#~ msgid ""
#~ "You cannot cancel a position that has been used to issue a gift card."
#~ msgstr ""
#~ "No podeu seleccionar una quota que pertany a un esdeveniment diferent."
#~ msgid "Automatically on payment"
#~ msgstr "Automàticament durant el pagament"
+231 -461
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-30 13:52+0000\n"
"POT-Creation-Date: 2026-07-07 09:30+0000\n"
"PO-Revision-Date: 2026-01-29 19:42+0000\n"
"Last-Translator: Jiří Pastrňák <jiri@pastrnak.email>\n"
"Language-Team: Czech <https://translate.pretix.eu/projects/pretix/pretix/cs/"
@@ -19,6 +19,38 @@ msgstr ""
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
"X-Generator: Weblate 5.15.2\n"
#: htmlcov/d_daa1541d0cbf5e2b_dashboards_py.html
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/views/dashboards.py
msgid "Shop disabled"
msgstr "Obchod vypnut"
#: htmlcov/d_daa1541d0cbf5e2b_dashboards_py.html pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/subevents/detail.html
#: pretix/control/templates/pretixcontrol/subevents/index.html
msgid "Presale over"
msgstr "Předprodej ukončen"
#: htmlcov/d_daa1541d0cbf5e2b_dashboards_py.html pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/subevents/detail.html
#: pretix/control/templates/pretixcontrol/subevents/index.html
msgid "Presale not started"
msgstr "Předprodej zatím nezačal"
#: htmlcov/d_daa1541d0cbf5e2b_dashboards_py.html
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/subevents/detail.html
#: pretix/control/templates/pretixcontrol/subevents/index.html
#: pretix/control/views/dashboards.py
msgid "On sale"
msgstr "V prodeji"
#: pretix/_base_settings.py
msgid "English"
msgstr "Angličtina"
@@ -1270,19 +1302,6 @@ msgstr "Zákaznické účty"
msgid "Download a spreadsheet of all currently registered customer accounts."
msgstr "Stažení tabulky všech aktuálně registrovaných zákaznických účtů."
#: pretix/base/exporters/customers.py pretix/base/permissions.py
#: pretix/control/navigation.py
#: pretix/control/templates/pretixcontrol/organizers/customers.html
msgid "Customers"
msgstr "Zákazníci"
#: pretix/base/exporters/customers.py pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/organizers/customer.html
#: pretix/presale/templates/pretixpresale/organizers/customer_memberships.html
#: pretix/presale/views/customer.py
msgid "Memberships"
msgstr "Členství"
#: pretix/base/exporters/customers.py pretix/base/models/customers.py
#: pretix/control/templates/pretixcontrol/organizers/customer.html
#: pretix/control/templates/pretixcontrol/organizers/customers.html
@@ -1415,71 +1434,6 @@ msgstr "Ano"
msgid "No"
msgstr "Ne"
#: pretix/base/exporters/customers.py pretix/base/exporters/orderlist.py
#: pretix/base/models/memberships.py pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/event/live.html
msgid "Test mode"
msgstr "Testovací režím"
#: pretix/base/exporters/customers.py pretix/base/models/memberships.py
#: pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/orders/fragment_order_status.html
#: pretix/control/templates/pretixcontrol/orders/overview.html
#: pretix/control/templates/pretixcontrol/organizers/customer_membership.html
#: pretix/plugins/reports/exporters.py
#: pretix/presale/templates/pretixpresale/event/fragment_order_status.html
#: pretix/presale/templates/pretixpresale/organizers/customer_membership.html
#: pretix/presale/templates/pretixpresale/organizers/customer_memberships.html
msgid "Canceled"
msgstr "Zrušeno"
#: pretix/base/exporters/customers.py pretix/base/models/memberships.py
#: pretix/control/templates/pretixcontrol/organizers/customer.html
#: pretix/presale/templates/pretixpresale/organizers/customer_membership.html
msgid "Membership type"
msgstr "Druh členství"
#: pretix/base/exporters/customers.py
#, fuzzy
msgid "Purchase ticket"
msgstr "Zakoupeno"
#: pretix/base/exporters/customers.py pretix/base/exporters/orderlist.py
#: pretix/base/exporters/waitinglist.py pretix/base/forms/questions.py
#: pretix/base/models/memberships.py pretix/control/forms/rrule.py
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/order/index.html
#: pretix/control/templates/pretixcontrol/orders/refunds.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/search/payments.html
#: pretix/control/templates/pretixcontrol/user/staff_session_edit.html
#: pretix/control/templates/pretixcontrol/user/staff_session_list.html
#: pretix/plugins/checkinlists/exporters.py
msgid "Start date"
msgstr "Datum začátku"
#: pretix/base/exporters/customers.py
#, fuzzy
#| msgid "Start time from"
msgid "Start time"
msgstr "Čas začátku od"
#: pretix/base/exporters/customers.py pretix/base/exporters/orderlist.py
#: pretix/base/exporters/waitinglist.py pretix/base/models/memberships.py
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/user/staff_session_edit.html
#: pretix/control/templates/pretixcontrol/user/staff_session_list.html
#: pretix/plugins/checkinlists/exporters.py
msgid "End date"
msgstr "Datum konce"
#: pretix/base/exporters/customers.py
#, fuzzy
#| msgid "End: %(time)s"
msgid "End time"
msgstr "Konec: %(time)s"
#: pretix/base/exporters/dekodi.py pretix/base/exporters/invoices.py
msgctxt "export_category"
msgid "Invoices"
@@ -2335,6 +2289,30 @@ msgstr "zrušeno"
msgid "Position ID"
msgstr "ID pozice"
#: pretix/base/exporters/orderlist.py pretix/base/exporters/waitinglist.py
#: pretix/base/forms/questions.py pretix/base/models/memberships.py
#: pretix/control/forms/rrule.py
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/order/index.html
#: pretix/control/templates/pretixcontrol/orders/refunds.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/search/payments.html
#: pretix/control/templates/pretixcontrol/user/staff_session_edit.html
#: pretix/control/templates/pretixcontrol/user/staff_session_list.html
#: pretix/plugins/checkinlists/exporters.py
msgid "Start date"
msgstr "Datum začátku"
#: pretix/base/exporters/orderlist.py pretix/base/exporters/waitinglist.py
#: pretix/base/models/memberships.py
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/user/staff_session_edit.html
#: pretix/control/templates/pretixcontrol/user/staff_session_list.html
#: pretix/plugins/checkinlists/exporters.py
msgid "End date"
msgstr "Datum konce"
#: pretix/base/exporters/orderlist.py pretix/base/exporters/waitinglist.py
#: pretix/base/modelimport_orders.py pretix/base/modelimport_vouchers.py
#: pretix/base/models/items.py pretix/base/models/vouchers.py
@@ -2739,6 +2717,12 @@ msgstr "Stáhněte si tabulku všech transakcí s dárkovými poukazy."
msgid "Gift card code"
msgstr "kód dárkové poukázky"
#: pretix/base/exporters/orderlist.py pretix/base/models/memberships.py
#: pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/event/live.html
msgid "Test mode"
msgstr "Testovací režím"
#: pretix/base/exporters/orderlist.py pretix/base/models/organizer.py
#: pretix/control/forms/event.py pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/email_setup.html
@@ -2855,7 +2839,7 @@ msgstr "Expirované a s hodnotou"
#: pretix/control/templates/pretixcontrol/orders/overview.html
#: pretix/control/templates/pretixcontrol/organizers/customer.html
#: pretix/control/templates/pretixcontrol/organizers/giftcards.html
#: pretix/plugins/reports/exporters.py pretix/plugins/sendmail/forms.py
#: pretix/plugins/reports/exporters.py
#: pretix/presale/templates/pretixpresale/event/fragment_order_status.html
#: pretix/presale/templates/pretixpresale/organizers/customer_giftcards.html
msgid "Expired"
@@ -3023,7 +3007,7 @@ msgid "This combination of credentials is not known to our system."
msgstr "Zadané přihlašovací údaje nejsou platné."
#: pretix/base/forms/auth.py pretix/base/forms/user.py
#: pretix/control/views/user.py pretix/presale/forms/customer.py
#: pretix/presale/forms/customer.py
msgid "For security reasons, please wait 5 minutes before you try again."
msgstr ""
"Z bezpečnostních důvodů, prosím, počkejte pět minut a potom to zkuste znovu."
@@ -3995,7 +3979,6 @@ msgstr "Ignorování kvóty"
#: pretix/base/modelimport_vouchers.py pretix/base/models/vouchers.py
#: pretix/control/templates/pretixcontrol/vouchers/bulk.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk_edit.html
#: pretix/control/templates/pretixcontrol/vouchers/detail.html
#: pretix/control/views/vouchers.py
msgid "Price effect"
@@ -4687,8 +4670,8 @@ msgstr ""
#: pretix/base/models/event.py
msgid ""
"This will be used to let users know if the event is in a different timezone, "
"and to let us calculate the local time of a user."
"This will be used to let users know if the event is in a different timezone "
"and lets us calculate users local times."
msgstr ""
#: pretix/base/models/event.py pretix/base/models/organizer.py
@@ -6155,6 +6138,23 @@ msgstr ""
msgid "Number of times this membership can be used in a purchase."
msgstr "Maximální počet využití."
#: pretix/base/models/memberships.py pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/orders/fragment_order_status.html
#: pretix/control/templates/pretixcontrol/orders/overview.html
#: pretix/control/templates/pretixcontrol/organizers/customer_membership.html
#: pretix/plugins/reports/exporters.py
#: pretix/presale/templates/pretixpresale/event/fragment_order_status.html
#: pretix/presale/templates/pretixpresale/organizers/customer_membership.html
#: pretix/presale/templates/pretixpresale/organizers/customer_memberships.html
msgid "Canceled"
msgstr "Zrušeno"
#: pretix/base/models/memberships.py
#: pretix/control/templates/pretixcontrol/organizers/customer.html
#: pretix/presale/templates/pretixpresale/organizers/customer_membership.html
msgid "Membership type"
msgstr "Druh členství"
#: pretix/base/models/orders.py
msgid "pending"
msgstr "chybějící"
@@ -6990,7 +6990,7 @@ msgstr "Tato varianta nepatří k tomuto produktu."
msgid "It is currently not possible to create vouchers for add-on products."
msgstr "V současné době není možné vytvářet poukazy na doplňkové produkty."
#: pretix/base/models/vouchers.py pretix/control/forms/vouchers.py
#: pretix/base/models/vouchers.py
msgid ""
"You need to select a specific product or quota if this voucher should "
"reserve tickets."
@@ -7013,7 +7013,7 @@ msgid ""
"usages."
msgstr "Maximální počet použití nesmí být nižší než minimální počet použití."
#: pretix/base/models/vouchers.py pretix/control/forms/vouchers.py
#: pretix/base/models/vouchers.py
msgid ""
"If you want this voucher to block quota, you need to select a specific date."
msgstr ""
@@ -7536,15 +7536,6 @@ msgstr "Tato dárková karta není organizátorem akce akceptována."
msgid "This gift card was used in the meantime. Please try again."
msgstr "Tato dárková karta byla mezitím použita. Zkuste to prosím znovu."
#: pretix/base/payment.py
#, fuzzy
#| msgid ""
#| "This payment provider does not exist or the respective plugin is disabled."
msgid ""
"This payment provider exists for historical purposes only and is no longer "
"usable."
msgstr "Tento poskytovatel plateb neexistuje nebo příslušný plugin je vypnutý."
#: pretix/base/pdf.py
msgid "Ticket code (barcode content)"
msgstr "Kód vstupenky (obsah čárkového kódu)"
@@ -8150,6 +8141,11 @@ msgid ""
"permissions."
msgstr ""
#: pretix/base/permissions.py pretix/control/navigation.py
#: pretix/control/templates/pretixcontrol/organizers/customers.html
msgid "Customers"
msgstr "Zákazníci"
#: pretix/base/permissions.py pretix/control/navigation.py
msgid "Devices"
msgstr "Zařízení"
@@ -9477,16 +9473,6 @@ msgid ""
"card."
msgstr "Cenu pozice, která byla použita k vydání dárkové karty, nelze změnit."
#: pretix/base/services/orders.py
#, fuzzy
#| msgid ""
#| "You cannot change the price of a position that has been used to issue a "
#| "gift card."
msgid ""
"You cannot change the ticket secret of a position that has been used to "
"issue a gift card."
msgstr "Cenu pozice, která byla použita k vydání dárkové karty, nelze změnit."
#: pretix/base/services/orders.py
#, python-brace-format
msgid ""
@@ -11302,13 +11288,13 @@ msgstr "Kontaktní e-mail"
msgid "We'll show this publicly to allow attendees to contact you."
msgstr "Tento údaj zobrazíme veřejně, aby vás účastníci mohli kontaktovat."
#: pretix/base/settings.py
#: pretix/base/settings.py pretix/control/forms/event.py
#, fuzzy
#| msgid "Contact"
msgid "Contact URL"
msgstr "Kontakt"
#: pretix/base/settings.py
#: pretix/base/settings.py pretix/control/forms/event.py
msgid ""
"If you set this, the footer contact link will point here instead of using "
"the email address above. Please note that you still need to add a contact "
@@ -13301,7 +13287,6 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/organizers/customer.html
#: pretix/control/templates/pretixcontrol/organizers/customer_membership.html
#: pretix/control/templates/pretixcontrol/organizers/customers.html
#: pretix/control/templates/pretixcontrol/organizers/devices.html
#: pretix/control/templates/pretixcontrol/organizers/giftcard.html
#: pretix/control/templates/pretixcontrol/organizers/giftcards.html
#: pretix/control/templates/pretixcontrol/organizers/reusable_media.html
@@ -14611,7 +14596,7 @@ msgstr "Všechny objednávky"
msgid "Valid orders"
msgstr "Platné objednávky"
#: pretix/control/forms/filter.py pretix/plugins/sendmail/forms.py
#: pretix/control/forms/filter.py
msgid "Paid (or canceled with paid fee)"
msgstr "Zaplaceno (nebo zrušeno se zaplaceným poplatkem)"
@@ -14635,7 +14620,7 @@ msgstr "Probíhající nebo zaplacené"
msgid "Cancellations"
msgstr "Storna"
#: pretix/control/forms/filter.py pretix/plugins/sendmail/forms.py
#: pretix/control/forms/filter.py
msgid "Canceled (fully)"
msgstr "Zrušeno (kompletní)"
@@ -14815,22 +14800,6 @@ msgstr "Obchod naživo a předprodej běží"
msgid "Inactive"
msgstr "Neaktivní"
#: pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/subevents/detail.html
#: pretix/control/templates/pretixcontrol/subevents/index.html
msgid "Presale not started"
msgstr "Předprodej zatím nezačal"
#: pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/subevents/detail.html
#: pretix/control/templates/pretixcontrol/subevents/index.html
msgid "Presale over"
msgstr "Předprodej ukončen"
#: pretix/control/forms/filter.py
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/import_form.html
msgid "Date from"
@@ -14868,6 +14837,13 @@ msgstr "aktivní"
msgid "not yet activated"
msgstr "zatím neaktivováno"
#: pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/organizers/customer.html
#: pretix/presale/templates/pretixpresale/organizers/customer_memberships.html
#: pretix/presale/views/customer.py
msgid "Memberships"
msgstr "Členství"
#: pretix/control/forms/filter.py
msgid "Has no memberships"
msgstr "Nemá žádné členství"
@@ -15097,42 +15073,6 @@ msgstr "Odvolaná zařízení"
msgid "Search email address or subject"
msgstr "Vyžadovat e-mailové adresy na lístek"
#: pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/order/index.html
#: pretix/control/templates/pretixcontrol/orders/refunds.html
msgid "Source"
msgstr "Zdroj"
#: pretix/control/forms/filter.py
#, fuzzy
#| msgid "All vouchers"
msgid "All sources"
msgstr "Všechny poukázky"
#: pretix/control/forms/filter.py
msgid "Team actions"
msgstr "Týmové akce"
#: pretix/control/forms/filter.py
msgid "Customer actions"
msgstr "Zákaznické akce"
#: pretix/control/forms/filter.py
#, fuzzy
#| msgid "Device status"
msgid "Device actions"
msgstr "Stav zařízení"
#: pretix/control/forms/filter.py
#, fuzzy
#| msgid "Order details"
msgid "User email"
msgstr "Podrobnosti o objednávce"
#: pretix/control/forms/filter.py pretix/control/navigation.py
msgid "All users"
msgstr "Všechny uživatelé"
#: pretix/control/forms/global_settings.py
msgid "Additional footer text"
msgstr "Další text v zápatí"
@@ -16500,7 +16440,6 @@ msgstr "Volitelné"
#: pretix/control/forms/renderers.py
#: pretix/control/templates/pretixcontrol/organizers/device_bulk_edit.html
#: pretix/control/templates/pretixcontrol/subevents/bulk_edit.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk_edit.html
msgctxt "form_bulk"
msgid "change"
msgstr "změnit"
@@ -16616,65 +16555,6 @@ msgstr ""
"Poukázka odpovídá pouze skrytým produktům, ale nezvolili jste, že je mají "
"zobrazit."
#: pretix/control/forms/vouchers.py
#, python-format
msgid ""
"You cannot reduce the maximum number of redemptions to %(max_usages)s, "
"because at least one of the selected vouchers has already been redeemed "
"%(max_redeemed)s times."
msgstr ""
#: pretix/control/forms/vouchers.py
#, fuzzy
#| msgid ""
#| "You cannot create a voucher that blocks quota as the selected product or "
#| "quota is currently sold out or completely reserved."
msgid ""
"You cannot create a voucher that allows selection of a quota but has no date "
"selected."
msgstr ""
"Nelze vytvořit poukaz, který blokuje kvótu, protože vybraný produkt nebo "
"kvóta jsou aktuálně vyprodány nebo zcela rezervovány."
#: pretix/control/forms/vouchers.py
#, fuzzy
#| msgid "The selected product does not allow to select a seat."
msgid "The selected quota does not match the selected subevent."
msgstr "Vybraný produkt neumožňuje výběr místa."
#: pretix/control/forms/vouchers.py
#, fuzzy
#| msgid ""
#| "There is not enough quota available on quota \"{}\" to perform the "
#| "operation."
msgid "There is no sufficient quota available to perform this change."
msgstr "Na kvótu „{}“ není k dispozici dostatek kvóty k provedení operace."
#: pretix/control/forms/vouchers.py
msgid ""
"Changing the maximum number of usages in bulk is not supported if any of the "
"selected vouchers is assigned a seat."
msgstr ""
#: pretix/control/forms/vouchers.py
msgctxt "subevent"
msgid ""
"Changing the date in bulk is not supported if any of the selected vouchers "
"is assigned a seat."
msgstr ""
#: pretix/control/forms/vouchers.py
msgid ""
"Changing the product to a quota is not supported if any of the selected "
"vouchers is assigned a seat."
msgstr ""
#: pretix/control/forms/vouchers.py
msgid ""
"This change cannot be completed because not all assigned seats of the "
"vouchers are still available"
msgstr ""
#: pretix/control/forms/vouchers.py
msgid "Codes"
msgstr "Kupónové kódy"
@@ -18533,6 +18413,10 @@ msgstr "Autorizované aplikace"
msgid "Account history"
msgstr "Historie účtu"
#: pretix/control/navigation.py
msgid "All users"
msgstr "Všechny uživatelé"
#: pretix/control/navigation.py
#: pretix/control/templates/pretixcontrol/user/staff_session_list.html
msgid "Admin sessions"
@@ -18811,7 +18695,6 @@ msgstr "Nastavit nové heslo"
#: pretix/control/templates/pretixcontrol/users/create.html
#: pretix/control/templates/pretixcontrol/users/form.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk_edit.html
#: pretix/control/templates/pretixcontrol/vouchers/detail.html
#: pretix/control/templates/pretixcontrol/waitinglist/edit.html
#: pretix/plugins/autocheckin/templates/pretixplugins/autocheckin/add.html
@@ -19267,8 +19150,8 @@ msgstr "Smazat"
#: pretix/control/templates/pretixcontrol/checkin/checkins.html
#: pretix/control/templates/pretixcontrol/checkin/index.html
#: pretix/control/templates/pretixcontrol/checkin/lists.html
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/fragment_log_filter_form.html
#: pretix/control/templates/pretixcontrol/items/question.html
#: pretix/control/templates/pretixcontrol/items/quotas.html
#: pretix/control/templates/pretixcontrol/orders/index.html
@@ -19279,6 +19162,7 @@ msgstr "Smazat"
#: pretix/control/templates/pretixcontrol/organizers/devices.html
#: pretix/control/templates/pretixcontrol/organizers/giftcards.html
#: pretix/control/templates/pretixcontrol/organizers/index.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
#: pretix/control/templates/pretixcontrol/organizers/outgoing_mails.html
#: pretix/control/templates/pretixcontrol/organizers/reusable_media.html
#: pretix/control/templates/pretixcontrol/organizers/teams.html
@@ -19413,7 +19297,6 @@ msgstr "Čas"
#: pretix/control/templates/pretixcontrol/organizers/devices.html
#: pretix/control/templates/pretixcontrol/organizers/outgoing_mails.html
#: pretix/control/templates/pretixcontrol/subevents/index.html
#: pretix/control/templates/pretixcontrol/vouchers/index.html
#: pretix/control/templates/pretixcontrol/waitinglist/index.html
msgid "Select all results on other pages as well"
msgstr "Vybrat všechny výsledky i na dalších stránkách"
@@ -20129,34 +20012,6 @@ msgid "We found an SPF record on your domain that includes this system. Great!"
msgstr ""
"Našli jsme záznam SPF na vaší doméně, který obsahuje tento systém. Skvělé!"
#: pretix/control/templates/pretixcontrol/email_setup_simple.html
#, fuzzy
#| msgid "Your new SPF record could look like this:"
msgid "Your new DKIM record should be set up as a CNAME record like this:"
msgstr "Váš nový záznam SPF může vypadat takto:"
#: pretix/control/templates/pretixcontrol/email_setup_simple.html
#, fuzzy
#| msgid ""
#| "We found an SPF record on your domain that includes this system. Great!"
msgid "We found a DKIM record on your domain for this system. Great!"
msgstr ""
"Našli jsme záznam SPF na vaší doméně, který obsahuje tento systém. Skvělé!"
#: pretix/control/templates/pretixcontrol/email_setup_simple.html
#, fuzzy
#| msgid "Your new SPF record could look like this:"
msgid "Your new DMARC record could look like this:"
msgstr "Váš nový záznam SPF může vypadat takto:"
#: pretix/control/templates/pretixcontrol/email_setup_simple.html
#, fuzzy
#| msgid ""
#| "We found an SPF record on your domain that includes this system. Great!"
msgid "We found a DMARC record on your domain for this system. Great!"
msgstr ""
"Našli jsme záznam SPF na vaší doméně, který obsahuje tento systém. Skvělé!"
#: pretix/control/templates/pretixcontrol/email_setup_simple.html
msgid "Verification"
msgstr "Ověřování"
@@ -20356,103 +20211,6 @@ msgstr ""
"nesmazatelná data, například objednávky, které nebyly provedeny v testovacím "
"režimu."
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_logs.html
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/includes/logs.html
#: pretix/control/templates/pretixcontrol/organizers/device_logs.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
msgid "Personal data was cleared from this log entry."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_logs.html
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/includes/logs.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
msgid "This change was performed by a pretix administrator."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_logs.html
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/includes/logs.html
#: pretix/control/templates/pretixcontrol/order/index.html
#: pretix/control/templates/pretixcontrol/organizers/device_logs.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
#: pretix/control/templates/pretixcontrol/search/payments.html
msgid "Inspect"
msgstr "Kontrola"
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid ""
"This event contains <strong>overpaid orders</strong>, for example due to "
"duplicate payment attempts. You should review the cases and consider "
"refunding the overpaid amount to the user."
msgstr ""
"Tato akce obsahuje <strong>přeplacené objednávky</strong>, například z "
"důvodu duplicitních pokusů o platbu. Měli byste tyto případy zkontrolovat a "
"uvažovat možnost vrácení přeplacené částky uživateli."
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid "Show overpaid orders"
msgstr "Zobrazit přeplacené objednávky"
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid ""
"This event contains <strong>pending refunds</strong> that you should take "
"care of."
msgstr ""
"Tato akce obsahuje <strong>nevyřízené náhrady</strong>, o které byste se "
"měli postarat."
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid "Show pending refunds"
msgstr "Zobrazit čekající náhrady"
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid ""
"This event contains <strong>requested cancellations</strong> that you should "
"take care of."
msgstr ""
"Tato akce obsahuje <strong>vyžádaná zrušení</strong>, o které byste se měli "
"postarat."
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid "Show orders requesting cancellation"
msgstr "Zobrazit objednávky s požadavkem na zrušení"
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid ""
"This event contains <strong>pending approvals</strong> that you should take "
"care of."
msgstr ""
"Tato akce obsahuje <strong>nevyřízená schválení</strong>, o která byste se "
"měli postarat."
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid "Show orders pending approval"
msgstr "Zobrazit objednávky čekající na schválení"
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid ""
"This event contains <strong>fully paid orders</strong> that are not marked "
"as paid, probably because no quota was left at the time their payment "
"arrived. You should review the cases and consider either refunding the "
"customer or creating more space."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid "Show affected orders"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid ""
"Orders in this event could not be <strong>synced to an external system</"
"strong> as configured."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid "Show sync problems"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/delete.html
msgid ""
"This operation will destroy your event including all configuration, "
@@ -20577,6 +20335,78 @@ msgstr "Adresa obchodu:"
msgid "Create QR code"
msgstr "Vytvořit kód QR"
#: pretix/control/templates/pretixcontrol/event/index.html
msgid ""
"This event contains <strong>overpaid orders</strong>, for example due to "
"duplicate payment attempts. You should review the cases and consider "
"refunding the overpaid amount to the user."
msgstr ""
"Tato akce obsahuje <strong>přeplacené objednávky</strong>, například z "
"důvodu duplicitních pokusů o platbu. Měli byste tyto případy zkontrolovat a "
"uvažovat možnost vrácení přeplacené částky uživateli."
#: pretix/control/templates/pretixcontrol/event/index.html
msgid "Show overpaid orders"
msgstr "Zobrazit přeplacené objednávky"
#: pretix/control/templates/pretixcontrol/event/index.html
msgid ""
"This event contains <strong>pending refunds</strong> that you should take "
"care of."
msgstr ""
"Tato akce obsahuje <strong>nevyřízené náhrady</strong>, o které byste se "
"měli postarat."
#: pretix/control/templates/pretixcontrol/event/index.html
msgid "Show pending refunds"
msgstr "Zobrazit čekající náhrady"
#: pretix/control/templates/pretixcontrol/event/index.html
msgid ""
"This event contains <strong>requested cancellations</strong> that you should "
"take care of."
msgstr ""
"Tato akce obsahuje <strong>vyžádaná zrušení</strong>, o které byste se měli "
"postarat."
#: pretix/control/templates/pretixcontrol/event/index.html
msgid "Show orders requesting cancellation"
msgstr "Zobrazit objednávky s požadavkem na zrušení"
#: pretix/control/templates/pretixcontrol/event/index.html
msgid ""
"This event contains <strong>pending approvals</strong> that you should take "
"care of."
msgstr ""
"Tato akce obsahuje <strong>nevyřízená schválení</strong>, o která byste se "
"měli postarat."
#: pretix/control/templates/pretixcontrol/event/index.html
msgid "Show orders pending approval"
msgstr "Zobrazit objednávky čekající na schválení"
#: pretix/control/templates/pretixcontrol/event/index.html
msgid ""
"This event contains <strong>fully paid orders</strong> that are not marked "
"as paid, probably because no quota was left at the time their payment "
"arrived. You should review the cases and consider either refunding the "
"customer or creating more space."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid "Show affected orders"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid ""
"Orders in this event could not be <strong>synced to an external system</"
"strong> as configured."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid "Show sync problems"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
#: pretix/control/templates/pretixcontrol/order/index.html
msgid "Update comment"
@@ -20758,6 +20588,44 @@ msgstr ""
msgid "Enable test mode"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
msgid "All actions"
msgstr "Všechny akce"
#: pretix/control/templates/pretixcontrol/event/logs.html
msgid "Team actions"
msgstr "Týmové akce"
#: pretix/control/templates/pretixcontrol/event/logs.html
msgid "Customer actions"
msgstr "Zákaznické akce"
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/event/logs_embed.html
#: pretix/control/templates/pretixcontrol/includes/logs.html
#: pretix/control/templates/pretixcontrol/organizers/device_logs.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
msgid "Personal data was cleared from this log entry."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/event/logs_embed.html
#: pretix/control/templates/pretixcontrol/includes/logs.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
msgid "This change was performed by a pretix administrator."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/event/logs_embed.html
#: pretix/control/templates/pretixcontrol/includes/logs.html
#: pretix/control/templates/pretixcontrol/order/index.html
#: pretix/control/templates/pretixcontrol/organizers/device_logs.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
#: pretix/control/templates/pretixcontrol/search/payments.html
msgid "Inspect"
msgstr "Kontrola"
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/organizers/device_logs.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
@@ -21720,20 +21588,6 @@ msgstr "Žádné termíny"
msgid "More quotas"
msgstr "Další kvóty"
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/views/dashboards.py
msgid "Shop disabled"
msgstr "Obchod vypnut"
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/subevents/detail.html
#: pretix/control/templates/pretixcontrol/subevents/index.html
#: pretix/control/views/dashboards.py
msgid "On sale"
msgstr "V prodeji"
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
msgid "Open event dashboard"
@@ -21744,12 +21598,6 @@ msgctxt "typography"
msgid "The quick brown fox jumps over the lazy dog."
msgstr ""
#: pretix/control/templates/pretixcontrol/fragment_log_filter_form.html
#, fuzzy
#| msgid "Specific seat"
msgid "Specific object selected"
msgstr "Přidělené místo"
#: pretix/control/templates/pretixcontrol/fragment_quota_box.html
#: pretix/control/templates/pretixcontrol/fragment_quota_box_paid.html
msgid "Quota:"
@@ -22806,7 +22654,6 @@ msgstr "Změnit více zařízení"
#: pretix/control/templates/pretixcontrol/items/quota_bulk_edit.html
#: pretix/control/templates/pretixcontrol/organizers/device_bulk_edit.html
#: pretix/control/templates/pretixcontrol/subevents/bulk_edit.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk_edit.html
#, python-format
msgid "%(number)s selected"
msgstr "%(number)s vybráno"
@@ -22903,7 +22750,6 @@ msgstr "Smazat vybrané"
#: pretix/control/templates/pretixcontrol/items/quotas.html
#: pretix/control/templates/pretixcontrol/organizers/devices.html
#: pretix/control/templates/pretixcontrol/subevents/index.html
#: pretix/control/templates/pretixcontrol/vouchers/index.html
msgid "Edit selected"
msgstr "Upravit vybrané"
@@ -23205,13 +23051,6 @@ msgid ""
"the customer account."
msgstr ""
#: pretix/control/templates/pretixcontrol/order/change.html
#: pretix/control/views/orders.py
msgid ""
"Ticket secrets of order positions that have been used to issue a gift card "
"can not be changed. Only the link will be changed in this case."
msgstr ""
#: pretix/control/templates/pretixcontrol/order/change.html
msgid ""
"Removing or splitting this position will also remove or split all add-ons to "
@@ -23648,6 +23487,11 @@ msgstr ""
msgid "Create a refund"
msgstr ""
#: pretix/control/templates/pretixcontrol/order/index.html
#: pretix/control/templates/pretixcontrol/orders/refunds.html
msgid "Source"
msgstr "Zdroj"
#: pretix/control/templates/pretixcontrol/order/index.html
msgid "Cancel transfer"
msgstr ""
@@ -24795,7 +24639,6 @@ msgstr "Změnit více zařízení"
#: pretix/control/templates/pretixcontrol/organizers/device_bulk_edit.html
#: pretix/control/templates/pretixcontrol/organizers/device_edit.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk_edit.html
#: pretix/control/templates/pretixcontrol/vouchers/detail.html
msgid "Advanced settings"
msgstr "Rozšířená nastavení"
@@ -27126,13 +26969,11 @@ msgid "Copy codes"
msgstr "Kopírovat kódy"
#: pretix/control/templates/pretixcontrol/vouchers/bulk.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk_edit.html
#: pretix/control/templates/pretixcontrol/vouchers/detail.html
msgid "Voucher details"
msgstr "Podrobnosti o poukázce"
#: pretix/control/templates/pretixcontrol/vouchers/bulk.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk_edit.html
#: pretix/control/templates/pretixcontrol/vouchers/detail.html
msgid ""
"If you choose \"any product\" for a specific quota and choose to reserve "
@@ -27140,12 +26981,6 @@ msgid ""
"voucher holder if another quota associated with the product is sold out!"
msgstr ""
#: pretix/control/templates/pretixcontrol/vouchers/bulk_edit.html
#, fuzzy
#| msgid "Change multiple devices"
msgid "Change multiple vouchers"
msgstr "Změnit více zařízení"
#: pretix/control/templates/pretixcontrol/vouchers/delete.html
#: pretix/control/templates/pretixcontrol/vouchers/detail.html
msgid "Delete voucher"
@@ -27502,8 +27337,7 @@ msgstr ""
#, python-brace-format
msgid ""
"You cannot accept the invitation for \"{}\" as you already are part of this "
"team. If you want to add a different user or create a new account, log out "
"and click the invitation link again."
"team."
msgstr ""
#: pretix/control/views/auth.py
@@ -28137,66 +27971,6 @@ msgstr ""
"Měli byste aktualizovat nastavení DNS své domény tak, aby zahrnovalo tento "
"systém v záznamu SPF."
#: pretix/control/views/mailsetup.py
#, fuzzy
#| msgid ""
#| "We could not find an SPF record set for the domain you are trying to use. "
#| "This means that there is a very high change most of the emails will be "
#| "rejected or marked as spam. We strongly recommend setting an SPF record "
#| "on the domain. You can do so through the DNS settings at the provider you "
#| "registered your domain with."
msgid ""
"We could not find a CNAME record pointing to our DKIM key for domain you are "
"trying to use. This means that there is a very high change most of the "
"emails will be rejected or marked as spam. We strongly recommend setting up "
"DKIM through a CNAME record. You can do so through the DNS settings at the "
"provider you registered your domain with."
msgstr ""
"Nepodařilo se nám najít záznam SPF nastavený pro doménu, kterou se snažíte "
"použít. To znamená, že je velmi vysoká pravděpodobnost, že většina e-mailů "
"bude odmítnuta nebo označena jako spam. Důrazně doporučujeme nastavit záznam "
"SPF pro danou doménu. Můžete tak učinit prostřednictvím nastavení DNS u "
"poskytovatele, u kterého jste doménu zaregistrovali."
#: pretix/control/views/mailsetup.py
#, fuzzy
#| msgid ""
#| "We found an SPF record set for the domain you are trying to use, but it "
#| "does not include this system's email server. This means that there is a "
#| "very high chance most of the emails will be rejected or marked as spam. "
#| "You should update the DNS settings of your domain to include this system "
#| "in the SPF record."
msgid ""
"We found a CNAME record for a DKIM key, but it is not pointing to the right "
"location. This means that there is a very high chance most of the emails "
"will be rejected or marked as spam. You should update the DNS settings of "
"your domain."
msgstr ""
"Našli jsme záznam SPF nastavený pro doménu, kterou se snažíte použít, ale "
"neobsahuje e-mailový server tohoto systému. To znamená, že je velmi vysoká "
"pravděpodobnost, že většina e-mailů bude odmítnuta nebo označena jako spam. "
"Měli byste aktualizovat nastavení DNS své domény tak, aby zahrnovalo tento "
"systém v záznamu SPF."
#: pretix/control/views/mailsetup.py
#, fuzzy
#| msgid ""
#| "We found an SPF record set for the domain you are trying to use, but it "
#| "does not include this system's email server. This means that there is a "
#| "very high chance most of the emails will be rejected or marked as spam. "
#| "You should update the DNS settings of your domain to include this system "
#| "in the SPF record."
msgid ""
"We did not find DMARC record for your domain. This means that there is a "
"very high chance most of the emails will be rejected or marked as spam. You "
"should update the DNS settings of your domain."
msgstr ""
"Našli jsme záznam SPF nastavený pro doménu, kterou se snažíte použít, ale "
"neobsahuje e-mailový server tohoto systému. To znamená, že je velmi vysoká "
"pravděpodobnost, že většina e-mailů bude odmítnuta nebo označena jako spam. "
"Měli byste aktualizovat nastavení DNS své domény tak, aby zahrnovalo tento "
"systém v záznamu SPF."
#: pretix/control/views/mailsetup.py
msgid "The verification code was incorrect, please try again."
msgstr ""
@@ -29299,7 +29073,6 @@ msgid "Macao"
msgstr ""
#: pretix/helpers/daterange.py
#: pretix/presale/templates/pretixpresale/event/fragment_subevent_list.html
#: pretix/presale/templates/pretixpresale/fragment_calendar.html
#: pretix/presale/templates/pretixpresale/fragment_week_calendar.html
#: pretix/presale/templates/pretixpresale/organizers/index.html
@@ -30562,6 +30335,11 @@ msgstr ""
msgid "PayPal account"
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
#, python-brace-format
msgid "<a target=\"_blank\" rel=\"noopener\" href=\"{docs_url}\">{text}</a>"
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid "Click here for a tutorial on how to obtain the required keys"
msgstr ""
@@ -31247,13 +31025,8 @@ msgstr "Přesměrování URL"
#: pretix/plugins/returnurl/views.py
msgid ""
"Redirection will only be allowed to URLs that start with one of these "
"prefixes. Enter one allowed URL prefix per line. URL prefixes must include a "
"slash after the hostname."
msgstr ""
#: pretix/plugins/returnurl/views.py
msgid ""
"All values must be URLs that include at last one slash after the hostname."
"prefixes. Enter one or more allowed URL prefix per line. URL prefixes must "
"include a slash after the hostname."
msgstr ""
#: pretix/plugins/sendmail/apps.py
@@ -36150,9 +35923,6 @@ msgstr "Přístup k zápisu"
msgid "Kosovo"
msgstr "Kosovo"
#~ msgid "All actions"
#~ msgstr "Všechny akce"
#, fuzzy
#~| msgid "Account information"
#~ msgid "Account invitation"
+222 -371
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-30 13:52+0000\n"
"POT-Creation-Date: 2026-07-07 09:30+0000\n"
"PO-Revision-Date: 2023-11-14 11:00+0000\n"
"Last-Translator: Charliecoleg <DM229135@colegsirgar.ac.uk>\n"
"Language-Team: Welsh <https://translate.pretix.eu/projects/pretix/pretix/cy/"
@@ -20,6 +20,38 @@ msgstr ""
"(n==3) ? 3 :(n==6) ? 4 : 5;\n"
"X-Generator: Weblate 5.1.1\n"
#: htmlcov/d_daa1541d0cbf5e2b_dashboards_py.html
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/views/dashboards.py
msgid "Shop disabled"
msgstr ""
#: htmlcov/d_daa1541d0cbf5e2b_dashboards_py.html pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/subevents/detail.html
#: pretix/control/templates/pretixcontrol/subevents/index.html
msgid "Presale over"
msgstr ""
#: htmlcov/d_daa1541d0cbf5e2b_dashboards_py.html pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/subevents/detail.html
#: pretix/control/templates/pretixcontrol/subevents/index.html
msgid "Presale not started"
msgstr ""
#: htmlcov/d_daa1541d0cbf5e2b_dashboards_py.html
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/subevents/detail.html
#: pretix/control/templates/pretixcontrol/subevents/index.html
#: pretix/control/views/dashboards.py
msgid "On sale"
msgstr ""
#: pretix/_base_settings.py
msgid "English"
msgstr "Saesneg"
@@ -1191,19 +1223,6 @@ msgstr ""
msgid "Download a spreadsheet of all currently registered customer accounts."
msgstr ""
#: pretix/base/exporters/customers.py pretix/base/permissions.py
#: pretix/control/navigation.py
#: pretix/control/templates/pretixcontrol/organizers/customers.html
msgid "Customers"
msgstr ""
#: pretix/base/exporters/customers.py pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/organizers/customer.html
#: pretix/presale/templates/pretixpresale/organizers/customer_memberships.html
#: pretix/presale/views/customer.py
msgid "Memberships"
msgstr ""
#: pretix/base/exporters/customers.py pretix/base/models/customers.py
#: pretix/control/templates/pretixcontrol/organizers/customer.html
#: pretix/control/templates/pretixcontrol/organizers/customers.html
@@ -1336,66 +1355,6 @@ msgstr ""
msgid "No"
msgstr ""
#: pretix/base/exporters/customers.py pretix/base/exporters/orderlist.py
#: pretix/base/models/memberships.py pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/event/live.html
msgid "Test mode"
msgstr ""
#: pretix/base/exporters/customers.py pretix/base/models/memberships.py
#: pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/orders/fragment_order_status.html
#: pretix/control/templates/pretixcontrol/orders/overview.html
#: pretix/control/templates/pretixcontrol/organizers/customer_membership.html
#: pretix/plugins/reports/exporters.py
#: pretix/presale/templates/pretixpresale/event/fragment_order_status.html
#: pretix/presale/templates/pretixpresale/organizers/customer_membership.html
#: pretix/presale/templates/pretixpresale/organizers/customer_memberships.html
msgid "Canceled"
msgstr ""
#: pretix/base/exporters/customers.py pretix/base/models/memberships.py
#: pretix/control/templates/pretixcontrol/organizers/customer.html
#: pretix/presale/templates/pretixpresale/organizers/customer_membership.html
msgid "Membership type"
msgstr ""
#: pretix/base/exporters/customers.py
msgid "Purchase ticket"
msgstr ""
#: pretix/base/exporters/customers.py pretix/base/exporters/orderlist.py
#: pretix/base/exporters/waitinglist.py pretix/base/forms/questions.py
#: pretix/base/models/memberships.py pretix/control/forms/rrule.py
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/order/index.html
#: pretix/control/templates/pretixcontrol/orders/refunds.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/search/payments.html
#: pretix/control/templates/pretixcontrol/user/staff_session_edit.html
#: pretix/control/templates/pretixcontrol/user/staff_session_list.html
#: pretix/plugins/checkinlists/exporters.py
msgid "Start date"
msgstr ""
#: pretix/base/exporters/customers.py
msgid "Start time"
msgstr ""
#: pretix/base/exporters/customers.py pretix/base/exporters/orderlist.py
#: pretix/base/exporters/waitinglist.py pretix/base/models/memberships.py
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/user/staff_session_edit.html
#: pretix/control/templates/pretixcontrol/user/staff_session_list.html
#: pretix/plugins/checkinlists/exporters.py
msgid "End date"
msgstr ""
#: pretix/base/exporters/customers.py
msgid "End time"
msgstr ""
#: pretix/base/exporters/dekodi.py pretix/base/exporters/invoices.py
msgctxt "export_category"
msgid "Invoices"
@@ -2223,6 +2182,30 @@ msgstr ""
msgid "Position ID"
msgstr ""
#: pretix/base/exporters/orderlist.py pretix/base/exporters/waitinglist.py
#: pretix/base/forms/questions.py pretix/base/models/memberships.py
#: pretix/control/forms/rrule.py
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/order/index.html
#: pretix/control/templates/pretixcontrol/orders/refunds.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/search/payments.html
#: pretix/control/templates/pretixcontrol/user/staff_session_edit.html
#: pretix/control/templates/pretixcontrol/user/staff_session_list.html
#: pretix/plugins/checkinlists/exporters.py
msgid "Start date"
msgstr ""
#: pretix/base/exporters/orderlist.py pretix/base/exporters/waitinglist.py
#: pretix/base/models/memberships.py
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/user/staff_session_edit.html
#: pretix/control/templates/pretixcontrol/user/staff_session_list.html
#: pretix/plugins/checkinlists/exporters.py
msgid "End date"
msgstr ""
#: pretix/base/exporters/orderlist.py pretix/base/exporters/waitinglist.py
#: pretix/base/modelimport_orders.py pretix/base/modelimport_vouchers.py
#: pretix/base/models/items.py pretix/base/models/vouchers.py
@@ -2614,6 +2597,12 @@ msgstr ""
msgid "Gift card code"
msgstr ""
#: pretix/base/exporters/orderlist.py pretix/base/models/memberships.py
#: pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/event/live.html
msgid "Test mode"
msgstr ""
#: pretix/base/exporters/orderlist.py pretix/base/models/organizer.py
#: pretix/control/forms/event.py pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/email_setup.html
@@ -2727,7 +2716,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/orders/overview.html
#: pretix/control/templates/pretixcontrol/organizers/customer.html
#: pretix/control/templates/pretixcontrol/organizers/giftcards.html
#: pretix/plugins/reports/exporters.py pretix/plugins/sendmail/forms.py
#: pretix/plugins/reports/exporters.py
#: pretix/presale/templates/pretixpresale/event/fragment_order_status.html
#: pretix/presale/templates/pretixpresale/organizers/customer_giftcards.html
msgid "Expired"
@@ -2893,7 +2882,7 @@ msgid "This combination of credentials is not known to our system."
msgstr ""
#: pretix/base/forms/auth.py pretix/base/forms/user.py
#: pretix/control/views/user.py pretix/presale/forms/customer.py
#: pretix/presale/forms/customer.py
msgid "For security reasons, please wait 5 minutes before you try again."
msgstr ""
@@ -3822,7 +3811,6 @@ msgstr ""
#: pretix/base/modelimport_vouchers.py pretix/base/models/vouchers.py
#: pretix/control/templates/pretixcontrol/vouchers/bulk.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk_edit.html
#: pretix/control/templates/pretixcontrol/vouchers/detail.html
#: pretix/control/views/vouchers.py
msgid "Price effect"
@@ -4440,8 +4428,8 @@ msgstr ""
#: pretix/base/models/event.py
msgid ""
"This will be used to let users know if the event is in a different timezone, "
"and to let us calculate the local time of a user."
"This will be used to let users know if the event is in a different timezone "
"and lets us calculate users local times."
msgstr ""
#: pretix/base/models/event.py pretix/base/models/organizer.py
@@ -5736,6 +5724,23 @@ msgstr ""
msgid "Number of times this membership can be used in a purchase."
msgstr ""
#: pretix/base/models/memberships.py pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/orders/fragment_order_status.html
#: pretix/control/templates/pretixcontrol/orders/overview.html
#: pretix/control/templates/pretixcontrol/organizers/customer_membership.html
#: pretix/plugins/reports/exporters.py
#: pretix/presale/templates/pretixpresale/event/fragment_order_status.html
#: pretix/presale/templates/pretixpresale/organizers/customer_membership.html
#: pretix/presale/templates/pretixpresale/organizers/customer_memberships.html
msgid "Canceled"
msgstr ""
#: pretix/base/models/memberships.py
#: pretix/control/templates/pretixcontrol/organizers/customer.html
#: pretix/presale/templates/pretixpresale/organizers/customer_membership.html
msgid "Membership type"
msgstr ""
#: pretix/base/models/orders.py
msgid "pending"
msgstr ""
@@ -6521,7 +6526,7 @@ msgstr ""
msgid "It is currently not possible to create vouchers for add-on products."
msgstr ""
#: pretix/base/models/vouchers.py pretix/control/forms/vouchers.py
#: pretix/base/models/vouchers.py
msgid ""
"You need to select a specific product or quota if this voucher should "
"reserve tickets."
@@ -6540,7 +6545,7 @@ msgid ""
"usages."
msgstr ""
#: pretix/base/models/vouchers.py pretix/control/forms/vouchers.py
#: pretix/base/models/vouchers.py
msgid ""
"If you want this voucher to block quota, you need to select a specific date."
msgstr ""
@@ -7009,12 +7014,6 @@ msgstr ""
msgid "This gift card was used in the meantime. Please try again."
msgstr ""
#: pretix/base/payment.py
msgid ""
"This payment provider exists for historical purposes only and is no longer "
"usable."
msgstr ""
#: pretix/base/pdf.py
msgid "Ticket code (barcode content)"
msgstr ""
@@ -7578,6 +7577,11 @@ msgid ""
"permissions."
msgstr ""
#: pretix/base/permissions.py pretix/control/navigation.py
#: pretix/control/templates/pretixcontrol/organizers/customers.html
msgid "Customers"
msgstr ""
#: pretix/base/permissions.py pretix/control/navigation.py
msgid "Devices"
msgstr ""
@@ -8717,12 +8721,6 @@ msgid ""
"card."
msgstr ""
#: pretix/base/services/orders.py
msgid ""
"You cannot change the ticket secret of a position that has been used to "
"issue a gift card."
msgstr ""
#: pretix/base/services/orders.py
#, python-brace-format
msgid ""
@@ -10260,13 +10258,13 @@ msgstr ""
msgid "We'll show this publicly to allow attendees to contact you."
msgstr ""
#: pretix/base/settings.py
#: pretix/base/settings.py pretix/control/forms/event.py
#, fuzzy
#| msgid "Content"
msgid "Contact URL"
msgstr "Cynnwys"
#: pretix/base/settings.py
#: pretix/base/settings.py pretix/control/forms/event.py
msgid ""
"If you set this, the footer contact link will point here instead of using "
"the email address above. Please note that you still need to add a contact "
@@ -11753,7 +11751,6 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/organizers/customer.html
#: pretix/control/templates/pretixcontrol/organizers/customer_membership.html
#: pretix/control/templates/pretixcontrol/organizers/customers.html
#: pretix/control/templates/pretixcontrol/organizers/devices.html
#: pretix/control/templates/pretixcontrol/organizers/giftcard.html
#: pretix/control/templates/pretixcontrol/organizers/giftcards.html
#: pretix/control/templates/pretixcontrol/organizers/reusable_media.html
@@ -12951,7 +12948,7 @@ msgstr ""
msgid "Valid orders"
msgstr ""
#: pretix/control/forms/filter.py pretix/plugins/sendmail/forms.py
#: pretix/control/forms/filter.py
msgid "Paid (or canceled with paid fee)"
msgstr ""
@@ -12975,7 +12972,7 @@ msgstr ""
msgid "Cancellations"
msgstr "Dileadau"
#: pretix/control/forms/filter.py pretix/plugins/sendmail/forms.py
#: pretix/control/forms/filter.py
msgid "Canceled (fully)"
msgstr ""
@@ -13150,22 +13147,6 @@ msgstr ""
msgid "Inactive"
msgstr ""
#: pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/subevents/detail.html
#: pretix/control/templates/pretixcontrol/subevents/index.html
msgid "Presale not started"
msgstr ""
#: pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/subevents/detail.html
#: pretix/control/templates/pretixcontrol/subevents/index.html
msgid "Presale over"
msgstr ""
#: pretix/control/forms/filter.py
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/import_form.html
msgid "Date from"
@@ -13203,6 +13184,13 @@ msgstr ""
msgid "not yet activated"
msgstr ""
#: pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/organizers/customer.html
#: pretix/presale/templates/pretixpresale/organizers/customer_memberships.html
#: pretix/presale/views/customer.py
msgid "Memberships"
msgstr ""
#: pretix/control/forms/filter.py
msgid "Has no memberships"
msgstr ""
@@ -13430,38 +13418,6 @@ msgstr ""
msgid "Search email address or subject"
msgstr ""
#: pretix/control/forms/filter.py
#: pretix/control/templates/pretixcontrol/order/index.html
#: pretix/control/templates/pretixcontrol/orders/refunds.html
msgid "Source"
msgstr "Tarddiad"
#: pretix/control/forms/filter.py
msgid "All sources"
msgstr ""
#: pretix/control/forms/filter.py
msgid "Team actions"
msgstr ""
#: pretix/control/forms/filter.py
msgid "Customer actions"
msgstr ""
#: pretix/control/forms/filter.py
#, fuzzy
#| msgid "Redirection"
msgid "Device actions"
msgstr "Ailgyfeiriad"
#: pretix/control/forms/filter.py
msgid "User email"
msgstr ""
#: pretix/control/forms/filter.py pretix/control/navigation.py
msgid "All users"
msgstr ""
#: pretix/control/forms/global_settings.py
msgid "Additional footer text"
msgstr ""
@@ -14649,7 +14605,6 @@ msgstr "Dewisol"
#: pretix/control/forms/renderers.py
#: pretix/control/templates/pretixcontrol/organizers/device_bulk_edit.html
#: pretix/control/templates/pretixcontrol/subevents/bulk_edit.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk_edit.html
msgctxt "form_bulk"
msgid "change"
msgstr "newid"
@@ -14763,55 +14718,6 @@ msgid ""
"should show them."
msgstr ""
#: pretix/control/forms/vouchers.py
#, python-format
msgid ""
"You cannot reduce the maximum number of redemptions to %(max_usages)s, "
"because at least one of the selected vouchers has already been redeemed "
"%(max_redeemed)s times."
msgstr ""
#: pretix/control/forms/vouchers.py
msgid ""
"You cannot create a voucher that allows selection of a quota but has no date "
"selected."
msgstr ""
#: pretix/control/forms/vouchers.py
#, fuzzy
#| msgid "The subevent does not belong to this event."
msgid "The selected quota does not match the selected subevent."
msgstr "Nid yw'r digwyddiad yn perthyn i'r digwyddiad hwn."
#: pretix/control/forms/vouchers.py
msgid "There is no sufficient quota available to perform this change."
msgstr ""
#: pretix/control/forms/vouchers.py
msgid ""
"Changing the maximum number of usages in bulk is not supported if any of the "
"selected vouchers is assigned a seat."
msgstr ""
#: pretix/control/forms/vouchers.py
msgctxt "subevent"
msgid ""
"Changing the date in bulk is not supported if any of the selected vouchers "
"is assigned a seat."
msgstr ""
#: pretix/control/forms/vouchers.py
msgid ""
"Changing the product to a quota is not supported if any of the selected "
"vouchers is assigned a seat."
msgstr ""
#: pretix/control/forms/vouchers.py
msgid ""
"This change cannot be completed because not all assigned seats of the "
"vouchers are still available"
msgstr ""
#: pretix/control/forms/vouchers.py
msgid "Codes"
msgstr ""
@@ -16518,6 +16424,10 @@ msgstr ""
msgid "Account history"
msgstr ""
#: pretix/control/navigation.py
msgid "All users"
msgstr ""
#: pretix/control/navigation.py
#: pretix/control/templates/pretixcontrol/user/staff_session_list.html
msgid "Admin sessions"
@@ -16786,7 +16696,6 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/users/create.html
#: pretix/control/templates/pretixcontrol/users/form.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk_edit.html
#: pretix/control/templates/pretixcontrol/vouchers/detail.html
#: pretix/control/templates/pretixcontrol/waitinglist/edit.html
#: pretix/plugins/autocheckin/templates/pretixplugins/autocheckin/add.html
@@ -17210,8 +17119,8 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/checkin/checkins.html
#: pretix/control/templates/pretixcontrol/checkin/index.html
#: pretix/control/templates/pretixcontrol/checkin/lists.html
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/fragment_log_filter_form.html
#: pretix/control/templates/pretixcontrol/items/question.html
#: pretix/control/templates/pretixcontrol/items/quotas.html
#: pretix/control/templates/pretixcontrol/orders/index.html
@@ -17222,6 +17131,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/organizers/devices.html
#: pretix/control/templates/pretixcontrol/organizers/giftcards.html
#: pretix/control/templates/pretixcontrol/organizers/index.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
#: pretix/control/templates/pretixcontrol/organizers/outgoing_mails.html
#: pretix/control/templates/pretixcontrol/organizers/reusable_media.html
#: pretix/control/templates/pretixcontrol/organizers/teams.html
@@ -17356,7 +17266,6 @@ msgstr "Stamp amser"
#: pretix/control/templates/pretixcontrol/organizers/devices.html
#: pretix/control/templates/pretixcontrol/organizers/outgoing_mails.html
#: pretix/control/templates/pretixcontrol/subevents/index.html
#: pretix/control/templates/pretixcontrol/vouchers/index.html
#: pretix/control/templates/pretixcontrol/waitinglist/index.html
msgid "Select all results on other pages as well"
msgstr ""
@@ -17927,22 +17836,6 @@ msgstr ""
msgid "We found an SPF record on your domain that includes this system. Great!"
msgstr ""
#: pretix/control/templates/pretixcontrol/email_setup_simple.html
msgid "Your new DKIM record should be set up as a CNAME record like this:"
msgstr ""
#: pretix/control/templates/pretixcontrol/email_setup_simple.html
msgid "We found a DKIM record on your domain for this system. Great!"
msgstr ""
#: pretix/control/templates/pretixcontrol/email_setup_simple.html
msgid "Your new DMARC record could look like this:"
msgstr ""
#: pretix/control/templates/pretixcontrol/email_setup_simple.html
msgid "We found a DMARC record on your domain for this system. Great!"
msgstr ""
#: pretix/control/templates/pretixcontrol/email_setup_simple.html
msgid "Verification"
msgstr ""
@@ -18103,94 +17996,6 @@ msgid ""
"undeletable data, such as orders not performed in test mode."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_logs.html
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/includes/logs.html
#: pretix/control/templates/pretixcontrol/organizers/device_logs.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
msgid "Personal data was cleared from this log entry."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_logs.html
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/includes/logs.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
msgid "This change was performed by a pretix administrator."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_logs.html
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/includes/logs.html
#: pretix/control/templates/pretixcontrol/order/index.html
#: pretix/control/templates/pretixcontrol/organizers/device_logs.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
#: pretix/control/templates/pretixcontrol/search/payments.html
msgid "Inspect"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid ""
"This event contains <strong>overpaid orders</strong>, for example due to "
"duplicate payment attempts. You should review the cases and consider "
"refunding the overpaid amount to the user."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid "Show overpaid orders"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid ""
"This event contains <strong>pending refunds</strong> that you should take "
"care of."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid "Show pending refunds"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid ""
"This event contains <strong>requested cancellations</strong> that you should "
"take care of."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid "Show orders requesting cancellation"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid ""
"This event contains <strong>pending approvals</strong> that you should take "
"care of."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid "Show orders pending approval"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid ""
"This event contains <strong>fully paid orders</strong> that are not marked "
"as paid, probably because no quota was left at the time their payment "
"arrived. You should review the cases and consider either refunding the "
"customer or creating more space."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid "Show affected orders"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid ""
"Orders in this event could not be <strong>synced to an external system</"
"strong> as configured."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/dashboard_partial_warnings.html
msgid "Show sync problems"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/delete.html
msgid ""
"This operation will destroy your event including all configuration, "
@@ -18305,6 +18110,69 @@ msgstr ""
msgid "Create QR code"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid ""
"This event contains <strong>overpaid orders</strong>, for example due to "
"duplicate payment attempts. You should review the cases and consider "
"refunding the overpaid amount to the user."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid "Show overpaid orders"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid ""
"This event contains <strong>pending refunds</strong> that you should take "
"care of."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid "Show pending refunds"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid ""
"This event contains <strong>requested cancellations</strong> that you should "
"take care of."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid "Show orders requesting cancellation"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid ""
"This event contains <strong>pending approvals</strong> that you should take "
"care of."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid "Show orders pending approval"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid ""
"This event contains <strong>fully paid orders</strong> that are not marked "
"as paid, probably because no quota was left at the time their payment "
"arrived. You should review the cases and consider either refunding the "
"customer or creating more space."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid "Show affected orders"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid ""
"Orders in this event could not be <strong>synced to an external system</"
"strong> as configured."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
msgid "Show sync problems"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/index.html
#: pretix/control/templates/pretixcontrol/order/index.html
msgid "Update comment"
@@ -18479,6 +18347,44 @@ msgstr ""
msgid "Enable test mode"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
msgid "All actions"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/logs.html
msgid "Team actions"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/logs.html
msgid "Customer actions"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/event/logs_embed.html
#: pretix/control/templates/pretixcontrol/includes/logs.html
#: pretix/control/templates/pretixcontrol/organizers/device_logs.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
msgid "Personal data was cleared from this log entry."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/event/logs_embed.html
#: pretix/control/templates/pretixcontrol/includes/logs.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
msgid "This change was performed by a pretix administrator."
msgstr ""
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/event/logs_embed.html
#: pretix/control/templates/pretixcontrol/includes/logs.html
#: pretix/control/templates/pretixcontrol/order/index.html
#: pretix/control/templates/pretixcontrol/organizers/device_logs.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
#: pretix/control/templates/pretixcontrol/search/payments.html
msgid "Inspect"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/logs.html
#: pretix/control/templates/pretixcontrol/organizers/device_logs.html
#: pretix/control/templates/pretixcontrol/organizers/logs.html
@@ -19396,20 +19302,6 @@ msgstr ""
msgid "More quotas"
msgstr ""
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/views/dashboards.py
msgid "Shop disabled"
msgstr ""
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
#: pretix/control/templates/pretixcontrol/subevents/detail.html
#: pretix/control/templates/pretixcontrol/subevents/index.html
#: pretix/control/views/dashboards.py
msgid "On sale"
msgstr ""
#: pretix/control/templates/pretixcontrol/events/index.html
#: pretix/control/templates/pretixcontrol/organizers/detail.html
msgid "Open event dashboard"
@@ -19420,10 +19312,6 @@ msgctxt "typography"
msgid "The quick brown fox jumps over the lazy dog."
msgstr ""
#: pretix/control/templates/pretixcontrol/fragment_log_filter_form.html
msgid "Specific object selected"
msgstr ""
#: pretix/control/templates/pretixcontrol/fragment_quota_box.html
#: pretix/control/templates/pretixcontrol/fragment_quota_box_paid.html
msgid "Quota:"
@@ -20454,7 +20342,6 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/items/quota_bulk_edit.html
#: pretix/control/templates/pretixcontrol/organizers/device_bulk_edit.html
#: pretix/control/templates/pretixcontrol/subevents/bulk_edit.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk_edit.html
#, python-format
msgid "%(number)s selected"
msgstr ""
@@ -20545,7 +20432,6 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/items/quotas.html
#: pretix/control/templates/pretixcontrol/organizers/devices.html
#: pretix/control/templates/pretixcontrol/subevents/index.html
#: pretix/control/templates/pretixcontrol/vouchers/index.html
msgid "Edit selected"
msgstr ""
@@ -20842,13 +20728,6 @@ msgid ""
"the customer account."
msgstr ""
#: pretix/control/templates/pretixcontrol/order/change.html
#: pretix/control/views/orders.py
msgid ""
"Ticket secrets of order positions that have been used to issue a gift card "
"can not be changed. Only the link will be changed in this case."
msgstr ""
#: pretix/control/templates/pretixcontrol/order/change.html
msgid ""
"Removing or splitting this position will also remove or split all add-ons to "
@@ -21263,6 +21142,11 @@ msgstr ""
msgid "Create a refund"
msgstr ""
#: pretix/control/templates/pretixcontrol/order/index.html
#: pretix/control/templates/pretixcontrol/orders/refunds.html
msgid "Source"
msgstr "Tarddiad"
#: pretix/control/templates/pretixcontrol/order/index.html
msgid "Cancel transfer"
msgstr ""
@@ -22353,7 +22237,6 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/organizers/device_bulk_edit.html
#: pretix/control/templates/pretixcontrol/organizers/device_edit.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk_edit.html
#: pretix/control/templates/pretixcontrol/vouchers/detail.html
msgid "Advanced settings"
msgstr ""
@@ -24534,13 +24417,11 @@ msgid "Copy codes"
msgstr ""
#: pretix/control/templates/pretixcontrol/vouchers/bulk.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk_edit.html
#: pretix/control/templates/pretixcontrol/vouchers/detail.html
msgid "Voucher details"
msgstr ""
#: pretix/control/templates/pretixcontrol/vouchers/bulk.html
#: pretix/control/templates/pretixcontrol/vouchers/bulk_edit.html
#: pretix/control/templates/pretixcontrol/vouchers/detail.html
msgid ""
"If you choose \"any product\" for a specific quota and choose to reserve "
@@ -24548,10 +24429,6 @@ msgid ""
"voucher holder if another quota associated with the product is sold out!"
msgstr ""
#: pretix/control/templates/pretixcontrol/vouchers/bulk_edit.html
msgid "Change multiple vouchers"
msgstr ""
#: pretix/control/templates/pretixcontrol/vouchers/delete.html
#: pretix/control/templates/pretixcontrol/vouchers/detail.html
msgid "Delete voucher"
@@ -24893,8 +24770,7 @@ msgstr ""
#, python-brace-format
msgid ""
"You cannot accept the invitation for \"{}\" as you already are part of this "
"team. If you want to add a different user or create a new account, log out "
"and click the invitation link again."
"team."
msgstr ""
#: pretix/control/views/auth.py
@@ -25505,30 +25381,6 @@ msgid ""
"record."
msgstr ""
#: pretix/control/views/mailsetup.py
msgid ""
"We could not find a CNAME record pointing to our DKIM key for domain you are "
"trying to use. This means that there is a very high change most of the "
"emails will be rejected or marked as spam. We strongly recommend setting up "
"DKIM through a CNAME record. You can do so through the DNS settings at the "
"provider you registered your domain with."
msgstr ""
#: pretix/control/views/mailsetup.py
msgid ""
"We found a CNAME record for a DKIM key, but it is not pointing to the right "
"location. This means that there is a very high chance most of the emails "
"will be rejected or marked as spam. You should update the DNS settings of "
"your domain."
msgstr ""
#: pretix/control/views/mailsetup.py
msgid ""
"We did not find DMARC record for your domain. This means that there is a "
"very high chance most of the emails will be rejected or marked as spam. You "
"should update the DNS settings of your domain."
msgstr ""
#: pretix/control/views/mailsetup.py
msgid "The verification code was incorrect, please try again."
msgstr ""
@@ -26592,7 +26444,6 @@ msgid "Macao"
msgstr ""
#: pretix/helpers/daterange.py
#: pretix/presale/templates/pretixpresale/event/fragment_subevent_list.html
#: pretix/presale/templates/pretixpresale/fragment_calendar.html
#: pretix/presale/templates/pretixpresale/fragment_week_calendar.html
#: pretix/presale/templates/pretixpresale/organizers/index.html
@@ -27789,6 +27640,11 @@ msgstr ""
msgid "PayPal account"
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
#, python-brace-format
msgid "<a target=\"_blank\" rel=\"noopener\" href=\"{docs_url}\">{text}</a>"
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid "Click here for a tutorial on how to obtain the required keys"
msgstr ""
@@ -28425,13 +28281,8 @@ msgstr "Ailgyfeirio URIs"
#: pretix/plugins/returnurl/views.py
msgid ""
"Redirection will only be allowed to URLs that start with one of these "
"prefixes. Enter one allowed URL prefix per line. URL prefixes must include a "
"slash after the hostname."
msgstr ""
#: pretix/plugins/returnurl/views.py
msgid ""
"All values must be URLs that include at last one slash after the hostname."
"prefixes. Enter one or more allowed URL prefix per line. URL prefixes must "
"include a slash after the hostname."
msgstr ""
#: pretix/plugins/sendmail/apps.py
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
-7
View File
@@ -94,8 +94,6 @@ Checkout
Chrome
Client-ID
Client-Secret
CNAME
CNAME-Eintrag
CODE.txt
Community-Übersetzungen
CONFIRM
@@ -125,11 +123,6 @@ Debug-Modus
dekodi
Desktop-Apps
Di
DKIM
DKIM-Eintrag
DKIM-Schlüssel
DMARC
DMARC-Eintrag
Do
Downloadformat
Dr
File diff suppressed because it is too large Load Diff
@@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-06 15:52+0000\n"
"PO-Revision-Date: 2026-07-13 11:28+0000\n"
"Last-Translator: Raphael Michel <michel@rami.io>\n"
"PO-Revision-Date: 2026-05-04 07:42+0000\n"
"Last-Translator: Martin Gross <gross@rami.io>\n"
"Language-Team: German (informal) <https://translate.pretix.eu/projects/"
"pretix/pretix-js/de_Informal/>\n"
"Language: de_Informal\n"
@@ -17,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 2026.7.1\n"
"X-Generator: Weblate 5.17\n"
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js
msgid "Marked as paid"
@@ -430,11 +430,11 @@ msgstr "Drücke Strg+C zum kopieren!"
#: pretix/static/pretixcontrol/js/ui/checkinrules/App.vue
msgid "Edit"
msgstr "Bearbeiten"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules/App.vue
msgid "Visualize"
msgstr "Visualisieren"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules/App.vue
msgid ""
@@ -442,13 +442,10 @@ msgid ""
"or variations are not contained in any of your rule parts so people with "
"these tickets will not get in:"
msgstr ""
"Deine Regeln filtern immer nach Produkt oder Variation, jedoch sind die "
"folgenden Produkte oder Variationen nicht in einer Ihrer Regeln enthalten, "
"sodass Kunden mit diesen Tickets keinen Eintritt erhalten werden:"
#: pretix/static/pretixcontrol/js/ui/checkinrules/App.vue
msgid "Please double-check if this was intentional."
msgstr "Bitte überprüfe, ob dies beabsichtigt war."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules/constants.ts
msgid "All of the conditions below (AND)"
@@ -94,8 +94,6 @@ Checkout
Chrome
Client-ID
Client-Secret
CNAME
CNAME-Eintrag
CODE.txt
Community-Übersetzungen
CONFIRM
@@ -125,11 +123,6 @@ Debug-Modus
dekodi
Desktop-Apps
Di
DKIM
DKIM-Eintrag
DKIM-Schlüssel
DMARC
DMARC-Eintrag
Do
Downloadformat
Dr

Some files were not shown because too many files have changed in this diff Show More