Compare commits

..
Author SHA1 Message Date
Raphael Michel 8759477cf5 Check-in: New scan type "print" 2023-08-11 14:48:23 +02:00
142 changed files with 902 additions and 30797 deletions
+1 -1
View File
@@ -34,7 +34,7 @@ Checking a ticket in
:<json string secret: Scanned QR code corresponding to the ``secret`` attribute of a ticket.
:<json string source_type: Type of source the ``secret`` was obtained form. Defaults to ``"barcode"``.
:<json array lists: List of check-in list IDs to search on. No two check-in lists may be from the same event.
:<json string type: Send ``"exit"`` for an exit and ``"entry"`` (default) for an entry.
:<json string type: Send ``"exit"`` for an exit and ``"entry"`` (default) for an entry, ``"print"`` for a badge print scan.
:<json datetime datetime: Specifies the datetime of the check-in. If not supplied, the current time will be used.
:<json boolean force: Specifies that the check-in should succeed regardless of revoked barcode, previous check-ins or required
questions that have not been filled. This is usually used to upload offline scans that already happened,
+1 -1
View File
@@ -631,7 +631,7 @@ Order position endpoints
:<json boolean force: Specifies that the check-in should succeed regardless of revoked barcode, previous check-ins or required
questions that have not been filled. This is usually used to upload offline scans that already happened,
because there's no point in validating them since they happened whether they are valid or not. Defaults to ``false``.
:<json string type: Send ``"exit"`` for an exit and ``"entry"`` (default) for an entry.
:<json string type: Send ``"exit"`` for an exit and ``"entry"`` (default) for an entry, ``"print"`` for a badge print scan.
:<json boolean ignore_unpaid: Specifies that the check-in should succeed even if the order is in pending state.
Defaults to ``false`` and only works when ``include_pending`` is set on the check-in
list.
+2 -33
View File
@@ -31,9 +31,9 @@ subevent_mode strings Determines h
``"same"`` (discount is only applied for groups within
the same date), or ``"distinct"`` (discount is only applied
for groups with no two same dates).
condition_all_products boolean If ``true``, the discount condition applies to all items.
condition_all_products boolean If ``true``, the discount applies to all items.
condition_limit_products list of integers If ``condition_all_products`` is not set, this is a list
of internal item IDs that the discount condition applies to.
of internal item IDs that the discount applies to.
condition_apply_to_addons boolean If ``true``, the discount applies to add-on products as well,
otherwise it only applies to top-level items. The discount never
applies to bundled products.
@@ -48,17 +48,6 @@ benefit_discount_matching_percent decimal (string) The percenta
benefit_only_apply_to_cheapest_n_matches integer If set higher than 0, the discount will only be applied to
the cheapest matches. Useful for a "3 for 2"-style discount.
Cannot be combined with ``condition_min_value``.
benefit_same_products boolean If ``true``, the discount benefit applies to the same set of items
as the condition (see above).
benefit_limit_products list of integers If ``benefit_same_products`` is not set, this is a list
of internal item IDs that the discount benefit applies to.
benefit_apply_to_addons boolean (Only used if ``benefit_same_products`` is ``false``.)
If ``true``, the discount applies to add-on products as well,
otherwise it only applies to top-level items. The discount never
applies to bundled products.
benefit_ignore_voucher_discounted boolean (Only used if ``benefit_same_products`` is ``false``.)
If ``true``, the discount does not apply to products which have
been discounted by a voucher.
======================================== ========================== =======================================================
@@ -105,10 +94,6 @@ Endpoints
"condition_ignore_voucher_discounted": false,
"condition_min_count": 3,
"condition_min_value": "0.00",
"benefit_same_products": true,
"benefit_limit_products": [],
"benefit_apply_to_addons": true,
"benefit_ignore_voucher_discounted": false,
"benefit_discount_matching_percent": "100.00",
"benefit_only_apply_to_cheapest_n_matches": 1
}
@@ -161,10 +146,6 @@ Endpoints
"condition_ignore_voucher_discounted": false,
"condition_min_count": 3,
"condition_min_value": "0.00",
"benefit_same_products": true,
"benefit_limit_products": [],
"benefit_apply_to_addons": true,
"benefit_ignore_voucher_discounted": false,
"benefit_discount_matching_percent": "100.00",
"benefit_only_apply_to_cheapest_n_matches": 1
}
@@ -203,10 +184,6 @@ Endpoints
"condition_ignore_voucher_discounted": false,
"condition_min_count": 3,
"condition_min_value": "0.00",
"benefit_same_products": true,
"benefit_limit_products": [],
"benefit_apply_to_addons": true,
"benefit_ignore_voucher_discounted": false,
"benefit_discount_matching_percent": "100.00",
"benefit_only_apply_to_cheapest_n_matches": 1
}
@@ -234,10 +211,6 @@ Endpoints
"condition_ignore_voucher_discounted": false,
"condition_min_count": 3,
"condition_min_value": "0.00",
"benefit_same_products": true,
"benefit_limit_products": [],
"benefit_apply_to_addons": true,
"benefit_ignore_voucher_discounted": false,
"benefit_discount_matching_percent": "100.00",
"benefit_only_apply_to_cheapest_n_matches": 1
}
@@ -294,10 +267,6 @@ Endpoints
"condition_ignore_voucher_discounted": false,
"condition_min_count": 3,
"condition_min_value": "0.00",
"benefit_same_products": true,
"benefit_limit_products": [],
"benefit_apply_to_addons": true,
"benefit_ignore_voucher_discounted": false,
"benefit_discount_matching_percent": "100.00",
"benefit_only_apply_to_cheapest_n_matches": 1
}
+2 -59
View File
@@ -12,7 +12,6 @@ The invoice resource contains the following public fields:
Field Type Description
===================================== ========================== =======================================================
number string Invoice number (with prefix)
event string The slug of the parent event
order string Order code of the order this invoice belongs to
is_cancellation boolean ``true``, if this invoice is the cancellation of a
different invoice.
@@ -122,13 +121,9 @@ internal_reference string Customer's refe
The attribute ``lines.subevent`` has been added.
.. versionchanged:: 2023.8
The ``event`` attribute has been added. The organizer-level endpoint has been added.
List of all invoices
--------------------
Endpoints
---------
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/invoices/
@@ -157,7 +152,6 @@ List of all invoices
"results": [
{
"number": "SAMPLECONF-00001",
"event": "sampleconf",
"order": "ABC12",
"is_cancellation": false,
"invoice_from_name": "Big Events LLC",
@@ -227,50 +221,6 @@ List of all invoices
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to view this resource.
.. http:get:: /api/v1/organizers/(organizer)/invoices/
Returns a list of all invoices within all events of a given organizer (with sufficient access permissions).
Supported query parameters and output format of this endpoint are identical to the list endpoint within an event.
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/bigevents/events/sampleconf/invoices/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: application/json
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"number": "SAMPLECONF-00001",
"event": "sampleconf",
"order": "ABC12",
...
]
}
:param organizer: The ``slug`` field of the organizer to fetch
:statuscode 200: no error
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to view this resource.
Fetching individual invoices
----------------------------
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/invoices/(number)/
Returns information on one invoice, identified by its invoice number.
@@ -293,7 +243,6 @@ Fetching individual invoices
{
"number": "SAMPLECONF-00001",
"event": "sampleconf",
"order": "ABC12",
"is_cancellation": false,
"invoice_from_name": "Big Events LLC",
@@ -388,12 +337,6 @@ Fetching individual invoices
:statuscode 409: The file is not yet ready and will now be prepared. Retry the request after waiting for a few
seconds.
Modifying invoices
------------------
Invoices cannot be edited directly, but the following actions can be triggered:
.. http:post:: /api/v1/organizers/(organizer)/events/(event)/invoices/(invoice_no)/reissue/
Cancels the invoice and creates a new one.
-49
View File
@@ -20,7 +20,6 @@ The order resource contains the following public fields:
Field Type Description
===================================== ========================== =======================================================
code string Order code
event string The slug of the parent event
status string Order status, one of:
* ``n`` pending
@@ -131,10 +130,6 @@ last_modified datetime Last modificati
The ``valid_if_pending`` attribute has been added.
.. versionchanged:: 2023.8
The ``event`` attribute has been added. The organizer-level endpoint has been added.
.. _order-position-resource:
@@ -294,7 +289,6 @@ List of all orders
"results": [
{
"code": "ABC12",
"event": "sampleconf",
"status": "p",
"testmode": false,
"secret": "k24fiuwvu8kxz3y1",
@@ -447,48 +441,6 @@ List of all orders
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to view this resource.
.. http:get:: /api/v1/organizers/(organizer)/orders/
Returns a list of all orders within all events of a given organizer (with sufficient access permissions).
Supported query parameters and output format of this endpoint are identical to the list endpoint within an event,
with the exception that the ``pdf_data`` parameter is not supported here.
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/bigevents/orders/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: application/json
X-Page-Generated: 2017-12-01T10:00:00Z
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"code": "ABC12",
"event": "sampleconf",
...
}
]
}
:param organizer: The ``slug`` field of the organizer to fetch
:statuscode 200: no error
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to view this resource.
Fetching individual orders
--------------------------
@@ -514,7 +466,6 @@ Fetching individual orders
{
"code": "ABC12",
"event": "sampleconf",
"status": "p",
"testmode": false,
"secret": "k24fiuwvu8kxz3y1",
+4 -13
View File
@@ -1,10 +1,10 @@
Scheduled email rules
Automated email rules
=====================
Resource description
--------------------
Scheduled email rules that specify emails that the system will send automatically at a specific point in time, e.g.
Automated email rules that specify emails that the system will send automatically at a specific point in time, e.g.
the day of the event.
.. rst-class:: rest-resource-table
@@ -23,14 +23,10 @@ limit_products list of integers List of product
restrict_to_status list List of order states to restrict recipients to. Valid
entries are ``p`` for paid, ``e`` for expired, ``c`` for canceled,
``n__pending_approval`` for pending approval,
``n__not_pending_approval_and_not_valid_if_pending`` for payment
pending, ``n__valid_if_pending`` for payment pending but already confirmed,
``n__not_pending_approval_and_not_valid_if_pending`` for payment pending,
``n__valid_if_pending`` for payment pending but already confirmed,
and ``n__pending_overdue`` for pending with payment overdue.
The default is ``["p", "n__valid_if_pending"]``.
checked_in_status string Check-in status to restrict recipients to. Valid strings are:
``null`` for no filtering (default), ``checked_in`` for
limiting to attendees that are or have been checked in, and
``no_checkin`` for limiting to attendees who have not checked in.
date_is_absolute boolean If ``true``, the email is set at a specific point in time.
send_date datetime If ``date_is_absolute`` is set: Date and time to send the email.
send_offset_days integer If ``date_is_absolute`` is not set, this is the number of days
@@ -93,7 +89,6 @@ Endpoints
"n__not_pending_approval_and_not_valid_if_pending",
"n__valid_if_pending"
],
"checked_in_status": null,
"send_date": null,
"send_offset_days": 1,
"send_offset_time": "18:00",
@@ -144,7 +139,6 @@ Endpoints
"n__not_pending_approval_and_not_valid_if_pending",
"n__valid_if_pending"
],
"checked_in_status": null,
"send_date": null,
"send_offset_days": 1,
"send_offset_time": "18:00",
@@ -186,7 +180,6 @@ Endpoints
"n__not_pending_approval_and_not_valid_if_pending",
"n__valid_if_pending"
],
"checked_in_status": "checked_in",
"send_date": null,
"send_offset_days": 1,
"send_offset_time": "18:00",
@@ -216,7 +209,6 @@ Endpoints
"n__not_pending_approval_and_not_valid_if_pending",
"n__valid_if_pending"
],
"checked_in_status": "checked_in",
"send_date": null,
"send_offset_days": 1,
"send_offset_time": "18:00",
@@ -274,7 +266,6 @@ Endpoints
"n__not_pending_approval_and_not_valid_if_pending",
"n__valid_if_pending"
],
"checked_in_status": "checked_in",
"send_date": null,
"send_offset_days": 1,
"send_offset_time": "18:00",
-14
View File
@@ -96,20 +96,6 @@ http://localhost:8000/control/ for the admin view.
port (for example because you develop on `pretixdroid`_), you can check
`Django's documentation`_ for more options.
When running the local development webserver, ensure Celery is not configured
in ``pretix.cfg``. i.e., you should remove anything such as::
[celery]
backend=redis://redis:6379/2
broker=redis://redis:6379/2
If you choose to use Celery for development, you must also start a Celery worker
process::
celery -A pretix.celery_app worker -l info
However, beware that code changes will not auto-reload within Celery.
.. _`checksandtests`:
Code checks and unit tests
+1 -2
View File
@@ -90,7 +90,7 @@ dependencies = [
"pytz-deprecation-shim==0.1.*",
"pyuca",
"qrcode==7.4.*",
"redis==4.6.*",
"redis==4.5.*,>=4.5.4",
"reportlab==4.0.*",
"requests==2.31.*",
"sentry-sdk==1.15.*",
@@ -112,7 +112,6 @@ memcached = ["pylibmc"]
dev = [
"coverage",
"coveralls",
"fakeredis==2.18.*",
"flake8==6.0.*",
"freezegun",
"isort==5.12.*",
+1 -3
View File
@@ -32,13 +32,11 @@ class DiscountSerializer(I18nAwareModelSerializer):
'available_until', 'subevent_mode', 'condition_all_products', 'condition_limit_products',
'condition_apply_to_addons', 'condition_min_count', 'condition_min_value',
'benefit_discount_matching_percent', 'benefit_only_apply_to_cheapest_n_matches',
'benefit_same_products', 'benefit_limit_products', 'benefit_apply_to_addons',
'benefit_ignore_voucher_discounted', 'condition_ignore_voucher_discounted')
'condition_ignore_voucher_discounted')
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['condition_limit_products'].queryset = self.context['event'].items.all()
self.fields['benefit_limit_products'].queryset = self.context['event'].items.all()
def validate(self, data):
data = super().validate(data)
+5 -22
View File
@@ -284,12 +284,11 @@ class FailedCheckinSerializer(I18nAwareModelSerializer):
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)
raw_subevent = serializers.PrimaryKeyRelatedField(queryset=SubEvent.objects.none(), required=False, allow_null=True)
nonce = serializers.CharField(required=False, allow_null=True)
class Meta:
model = Checkin
fields = ('error_reason', 'error_explanation', 'raw_barcode', 'raw_item', 'raw_variation',
'raw_subevent', 'nonce', 'datetime', 'type', 'position')
'raw_subevent', 'datetime', 'type', 'position')
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
@@ -507,20 +506,6 @@ class OrderPositionSerializer(I18nAwareModelSerializer):
def validate(self, data):
raise TypeError("this serializer is readonly")
def to_representation(self, data):
if isinstance(self.parent, (OrderListSerializer, OrderPositionListSerializer)):
# Do not execute our custom code because it will be executed by OrderListSerializer later for the
# full result set.
return super().to_representation(data)
entry = super().to_representation(data)
if "pdf_data" in entry:
for k, v in entry["pdf_data"].items():
if isinstance(v, tuple) and callable(v[0]):
entry["pdf_data"][k] = v[0]([v[1]])[0]
return entry
class RequireAttentionField(serializers.Field):
def to_representation(self, instance: OrderPosition):
@@ -615,7 +600,7 @@ class PaymentURLField(serializers.URLField):
def to_representation(self, instance: OrderPayment):
if instance.state != OrderPayment.PAYMENT_STATE_CREATED:
return None
return build_absolute_uri(instance.order.event, 'presale:event.order.pay', kwargs={
return build_absolute_uri(self.context['event'], 'presale:event.order.pay', kwargs={
'order': instance.order.code,
'secret': instance.order.secret,
'payment': instance.pk,
@@ -660,7 +645,7 @@ class OrderRefundSerializer(I18nAwareModelSerializer):
class OrderURLField(serializers.URLField):
def to_representation(self, instance: Order):
return build_absolute_uri(instance.event, 'presale:event.order', kwargs={
return build_absolute_uri(self.context['event'], 'presale:event.order', kwargs={
'order': instance.code,
'secret': instance.secret,
})
@@ -695,7 +680,6 @@ class OrderListSerializer(serializers.ListSerializer):
class OrderSerializer(I18nAwareModelSerializer):
event = SlugRelatedField(slug_field='slug', read_only=True)
invoice_address = InvoiceAddressSerializer(allow_null=True)
positions = OrderPositionSerializer(many=True, read_only=True)
fees = OrderFeeSerializer(many=True, read_only=True)
@@ -711,7 +695,7 @@ class OrderSerializer(I18nAwareModelSerializer):
model = Order
list_serializer_class = OrderListSerializer
fields = (
'code', 'event', 'status', 'testmode', 'secret', 'email', 'phone', 'locale', 'datetime', 'expires', 'payment_date',
'code', 'status', 'testmode', 'secret', 'email', 'phone', 'locale', 'datetime', 'expires', 'payment_date',
'payment_provider', 'fees', 'total', 'comment', 'custom_followup_at', 'invoice_address', 'positions', 'downloads',
'checkin_attention', 'last_modified', 'payments', 'refunds', 'require_approval', 'sales_channel',
'url', 'customer', 'valid_if_pending'
@@ -1595,7 +1579,6 @@ class InlineInvoiceLineSerializer(I18nAwareModelSerializer):
class InvoiceSerializer(I18nAwareModelSerializer):
event = SlugRelatedField(slug_field='slug', read_only=True)
order = serializers.SlugRelatedField(slug_field='code', read_only=True)
refers = serializers.SlugRelatedField(slug_field='full_invoice_no', read_only=True)
lines = InlineInvoiceLineSerializer(many=True)
@@ -1604,7 +1587,7 @@ class InvoiceSerializer(I18nAwareModelSerializer):
class Meta:
model = Invoice
fields = ('event', 'order', 'number', 'is_cancellation', 'invoice_from', 'invoice_from_name', 'invoice_from_zipcode',
fields = ('order', 'number', 'is_cancellation', 'invoice_from', 'invoice_from_name', 'invoice_from_zipcode',
'invoice_from_city', 'invoice_from_country', 'invoice_from_tax_id', 'invoice_from_vat_id',
'invoice_to', 'invoice_to_company', 'invoice_to_name', 'invoice_to_street', 'invoice_to_zipcode',
'invoice_to_city', 'invoice_to_state', 'invoice_to_country', 'invoice_to_vat_id', 'invoice_to_beneficiary',
-8
View File
@@ -94,14 +94,6 @@ class CustomerSerializer(I18nAwareModelSerializer):
data['name_parts']['_scheme'] = self.context['request'].organizer.settings.name_scheme
return data
def validate_email(self, value):
qs = Customer.objects.filter(organizer=self.context['organizer'], email__iexact=value)
if self.instance and self.instance.pk:
qs = qs.exclude(pk=self.instance.pk)
if qs.exists():
raise ValidationError(_("An account with this email address is already registered."))
return value
class CustomerCreateSerializer(CustomerSerializer):
send_email = serializers.BooleanField(default=False, required=False, allow_null=True)
+1 -3
View File
@@ -61,8 +61,6 @@ orga_router.register(r'membershiptypes', organizer.MembershipTypeViewSet)
orga_router.register(r'reusablemedia', media.ReusableMediaViewSet)
orga_router.register(r'teams', organizer.TeamViewSet)
orga_router.register(r'devices', organizer.DeviceViewSet)
orga_router.register(r'orders', order.OrganizerOrderViewSet)
orga_router.register(r'invoices', order.InvoiceViewSet)
orga_router.register(r'exporters', exporters.OrganizerExportersViewSet, basename='exporters')
team_router = routers.DefaultRouter()
@@ -79,7 +77,7 @@ event_router.register(r'questions', item.QuestionViewSet)
event_router.register(r'discounts', discount.DiscountViewSet)
event_router.register(r'quotas', item.QuotaViewSet)
event_router.register(r'vouchers', voucher.VoucherViewSet)
event_router.register(r'orders', order.EventOrderViewSet)
event_router.register(r'orders', order.OrderViewSet)
event_router.register(r'orderpositions', order.OrderPositionViewSet)
event_router.register(r'invoices', order.InvoiceViewSet)
event_router.register(r'revokedsecrets', order.RevokedSecretViewSet, basename='revokedsecrets')
+1 -14
View File
@@ -164,21 +164,8 @@ class CheckinListViewSet(viewsets.ModelViewSet):
secret=serializer.validated_data['raw_barcode']
).first()
clist = self.get_object()
if serializer.validated_data.get('nonce'):
if kwargs.get('position'):
prev = kwargs['position'].all_checkins.filter(nonce=serializer.validated_data['nonce']).first()
else:
prev = clist.checkins.filter(
nonce=serializer.validated_data['nonce'],
raw_barcode=serializer.validated_data['raw_barcode'],
).first()
if prev:
# Ignore because nonce is already handled
return Response(serializer.data, status=201)
c = serializer.save(
list=clist,
list=self.get_object(),
successful=False,
forced=True,
force_sent=True,
-1
View File
@@ -415,7 +415,6 @@ class SubEventViewSet(ConditionalListView, viewsets.ModelViewSet):
'subeventitem_set',
'subeventitemvariation_set',
'meta_values',
'meta_values__property',
Prefetch(
'seat_category_mappings',
to_attr='_seat_category_mappings',
+25 -71
View File
@@ -44,7 +44,6 @@ from rest_framework.exceptions import (
APIException, NotFound, PermissionDenied, ValidationError,
)
from rest_framework.mixins import CreateModelMixin
from rest_framework.permissions import SAFE_METHODS
from rest_framework.response import Response
from pretix.api.models import OAuthAccessToken
@@ -186,7 +185,7 @@ with scopes_disabled():
)
class OrderViewSetMixin:
class OrderViewSet(viewsets.ModelViewSet):
serializer_class = OrderSerializer
queryset = Order.objects.none()
filter_backends = (DjangoFilterBackend, TotalOrderingFilter)
@@ -194,12 +193,19 @@ class OrderViewSetMixin:
ordering_fields = ('datetime', 'code', 'status', 'last_modified')
filterset_class = OrderFilter
lookup_field = 'code'
permission = 'can_view_orders'
write_permission = 'can_change_orders'
def get_base_queryset(self):
raise NotImplementedError()
def get_serializer_context(self):
ctx = super().get_serializer_context()
ctx['event'] = self.request.event
ctx['pdf_data'] = self.request.query_params.get('pdf_data', 'false') == 'true'
ctx['exclude'] = self.request.query_params.getlist('exclude')
ctx['include'] = self.request.query_params.getlist('include')
return ctx
def get_queryset(self):
qs = self.get_base_queryset()
qs = self.request.event.orders
if 'fees' not in self.request.GET.getlist('exclude'):
if self.request.query_params.get('include_canceled_fees', 'false') == 'true':
fqs = OrderFee.all
@@ -221,12 +227,11 @@ class OrderViewSetMixin:
opq = OrderPosition.all
else:
opq = OrderPosition.objects
if request.query_params.get('pdf_data', 'false') == 'true' and getattr(request, 'event', None):
if request.query_params.get('pdf_data', 'false') == 'true':
prefetch_related_objects([request.organizer], 'meta_properties')
prefetch_related_objects(
[request.event],
Prefetch('meta_values', queryset=EventMetaValue.objects.select_related('property'),
to_attr='meta_values_cached'),
Prefetch('meta_values', queryset=EventMetaValue.objects.select_related('property'), to_attr='meta_values_cached'),
'questions',
'item_meta_properties',
)
@@ -261,12 +266,13 @@ class OrderViewSetMixin:
)
)
def get_serializer_context(self):
ctx = super().get_serializer_context()
ctx['exclude'] = self.request.query_params.getlist('exclude')
ctx['include'] = self.request.query_params.getlist('include')
ctx['pdf_data'] = False
return ctx
def _get_output_provider(self, identifier):
responses = register_ticket_outputs.send(self.request.event)
for receiver, response in responses:
prov = response(self.request.event)
if prov.identifier == identifier:
return prov
raise NotFound('Unknown output provider.')
@scopes_disabled() # we are sure enough that get_queryset() is correct, so we save some perforamnce
def list(self, request, **kwargs):
@@ -283,45 +289,6 @@ class OrderViewSetMixin:
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data, headers={'X-Page-Generated': date})
class OrganizerOrderViewSet(OrderViewSetMixin, viewsets.ReadOnlyModelViewSet):
def get_base_queryset(self):
perm = "can_view_orders" if self.request.method in SAFE_METHODS else "can_change_orders"
if isinstance(self.request.auth, (TeamAPIToken, Device)):
return Order.objects.filter(
event__organizer=self.request.organizer,
event__in=self.request.auth.get_events_with_permission(perm)
)
elif self.request.user.is_authenticated:
return Order.objects.filter(
event__organizer=self.request.organizer,
event__in=self.request.user.get_events_with_permission(perm)
)
else:
raise PermissionDenied()
class EventOrderViewSet(OrderViewSetMixin, viewsets.ModelViewSet):
permission = 'can_view_orders'
write_permission = 'can_change_orders'
def get_serializer_context(self):
ctx = super().get_serializer_context()
ctx['event'] = self.request.event
ctx['pdf_data'] = self.request.query_params.get('pdf_data', 'false') == 'true'
return ctx
def get_base_queryset(self):
return self.request.event.orders
def _get_output_provider(self, identifier):
responses = register_ticket_outputs.send(self.request.event)
for receiver, response in responses:
prov = response(self.request.event)
if prov.identifier == identifier:
return prov
raise NotFound('Unknown output provider.')
@action(detail=True, url_name='download', url_path='download/(?P<output>[^/]+)')
def download(self, request, output, **kwargs):
provider = self._get_output_provider(output)
@@ -1815,24 +1782,11 @@ class InvoiceViewSet(viewsets.ReadOnlyModelViewSet):
write_permission = 'can_change_orders'
def get_queryset(self):
perm = "can_view_orders" if self.request.method in SAFE_METHODS else "can_change_orders"
if getattr(self.request, 'event', None):
qs = self.request.event.invoices
elif isinstance(self.request.auth, (TeamAPIToken, Device)):
qs = Invoice.objects.filter(
event__organizer=self.request.organizer,
event__in=self.request.auth.get_events_with_permission(perm)
)
elif self.request.user.is_authenticated:
qs = Invoice.objects.filter(
event__organizer=self.request.organizer,
event__in=self.request.user.get_events_with_permission(perm)
)
return qs.prefetch_related('lines').select_related('order', 'refers').annotate(
return self.request.event.invoices.prefetch_related('lines').select_related('order', 'refers').annotate(
nr=Concat('prefix', 'invoice_no')
)
@action(detail=True)
@action(detail=True, )
def download(self, request, **kwargs):
invoice = self.get_object()
@@ -1851,7 +1805,7 @@ class InvoiceViewSet(viewsets.ReadOnlyModelViewSet):
return resp
@action(detail=True, methods=['POST'])
def regenerate(self, request, **kwargs):
def regenerate(self, request, **kwarts):
inv = self.get_object()
if inv.canceled:
raise ValidationError('The invoice has already been canceled.')
@@ -1861,7 +1815,7 @@ class InvoiceViewSet(viewsets.ReadOnlyModelViewSet):
raise PermissionDenied('The invoice file is no longer stored on the server.')
elif inv.sent_to_organizer:
raise PermissionDenied('The invoice file has already been exported.')
elif now().astimezone(inv.event.timezone).date() - inv.date > datetime.timedelta(days=1):
elif now().astimezone(self.request.event.timezone).date() - inv.date > datetime.timedelta(days=1):
raise PermissionDenied('The invoice file is too old to be regenerated.')
else:
inv = regenerate_invoice(inv)
@@ -1876,7 +1830,7 @@ class InvoiceViewSet(viewsets.ReadOnlyModelViewSet):
return Response(status=204)
@action(detail=True, methods=['POST'])
def reissue(self, request, **kwargs):
def reissue(self, request, **kwarts):
inv = self.get_object()
if inv.canceled:
raise ValidationError('The invoice has already been canceled.')
+5 -5
View File
@@ -62,27 +62,27 @@ class NamespacedCache:
prefix = int(time.time())
self.cache.set(self.prefixkey, prefix)
def set(self, key: str, value: any, timeout: int=300):
def set(self, key: str, value: str, timeout: int=300):
return self.cache.set(self._prefix_key(key), value, timeout)
def get(self, key: str) -> any:
def get(self, key: str) -> str:
return self.cache.get(self._prefix_key(key, known_prefix=self._last_prefix))
def get_or_set(self, key: str, default: Callable, timeout=300) -> any:
def get_or_set(self, key: str, default: Callable, timeout=300) -> str:
return self.cache.get_or_set(
self._prefix_key(key, known_prefix=self._last_prefix),
default=default,
timeout=timeout
)
def get_many(self, keys: List[str]) -> Dict[str, any]:
def get_many(self, keys: List[str]) -> Dict[str, str]:
values = self.cache.get_many([self._prefix_key(key) for key in keys])
newvalues = {}
for k, v in values.items():
newvalues[self._strip_prefix(k)] = v
return newvalues
def set_many(self, values: Dict[str, any], timeout=300):
def set_many(self, values: Dict[str, str], timeout=300):
newvalues = {}
for k, v in values.items():
newvalues[self._prefix_key(k)] = v
+2 -5
View File
@@ -134,11 +134,8 @@ class TemplateBasedMailRenderer(BaseHTMLMailRenderer):
def template_name(self):
raise NotImplementedError()
def compile_markdown(self, plaintext):
return markdown_compile_email(plaintext)
def render(self, plain_body: str, plain_signature: str, subject: str, order, position) -> str:
body_md = self.compile_markdown(plain_body)
body_md = markdown_compile_email(plain_body)
htmlctx = {
'site': settings.PRETIX_INSTANCE_NAME,
'site_url': settings.SITE_URL,
@@ -156,7 +153,7 @@ class TemplateBasedMailRenderer(BaseHTMLMailRenderer):
if plain_signature:
signature_md = plain_signature.replace('\n', '<br>\n')
signature_md = self.compile_markdown(signature_md)
signature_md = markdown_compile_email(signature_md)
htmlctx['signature'] = signature_md
if order:
-4
View File
@@ -549,9 +549,7 @@ class OrderListExporter(MultiSheetListExporter):
headers.append(_('End date'))
headers += [
_('Product'),
_('Product ID'),
_('Variation'),
_('Variation ID'),
_('Price'),
_('Tax rate'),
_('Tax rule'),
@@ -658,9 +656,7 @@ class OrderListExporter(MultiSheetListExporter):
row.append('')
row += [
str(op.item),
str(op.item_id),
str(op.variation) if op.variation else '',
str(op.variation_id) if op.variation_id else '',
op.price,
op.tax_rate,
str(op.tax_rule) if op.tax_rule else '',
@@ -1,34 +0,0 @@
# Generated by Django 4.2.4 on 2023-08-28 12:30
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("pretixbase", "0244_mediumkeyset"),
]
operations = [
migrations.AddField(
model_name="discount",
name="benefit_apply_to_addons",
field=models.BooleanField(default=True),
),
migrations.AddField(
model_name="discount",
name="benefit_ignore_voucher_discounted",
field=models.BooleanField(default=False),
),
migrations.AddField(
model_name="discount",
name="benefit_limit_products",
field=models.ManyToManyField(
related_name="benefit_discounts", to="pretixbase.item"
),
),
migrations.AddField(
model_name="discount",
name="benefit_same_products",
field=models.BooleanField(default=True),
),
]
+3 -1
View File
@@ -179,7 +179,7 @@ class CheckinList(LoggedModel):
# dedupliate by position and count it up.
cl = self
base_q, base_params = (
Checkin.all.filter(*c_q, successful=True, list=cl)
Checkin.all.filter(*c_q, successful=True, list=cl, type__in=[Checkin.TYPE_ENTRY, Checkin.TYPE_EXIT])
.annotate(
cnt_exists_after=Window(
expression=Count("position_id", filter=Q(type=Value("exit"))),
@@ -322,9 +322,11 @@ class Checkin(models.Model):
"""
TYPE_ENTRY = 'entry'
TYPE_EXIT = 'exit'
TYPE_PRINT = 'print'
CHECKIN_TYPES = (
(TYPE_ENTRY, _('Entry')),
(TYPE_EXIT, _('Exit')),
(TYPE_PRINT, _('Print')),
)
REASON_CANCELED = 'canceled'
+23 -74
View File
@@ -99,7 +99,7 @@ class Discount(LoggedModel):
)
condition_apply_to_addons = models.BooleanField(
default=True,
verbose_name=_("Count add-on products"),
verbose_name=_("Apply to add-on products"),
help_text=_("Discounts never apply to bundled products"),
)
condition_ignore_voucher_discounted = models.BooleanField(
@@ -107,7 +107,7 @@ class Discount(LoggedModel):
verbose_name=_("Ignore products discounted by a voucher"),
help_text=_("If this option is checked, products that already received a discount through a voucher will not "
"be considered for this discount. However, products that use a voucher only to e.g. unlock a "
"hidden product or gain access to sold-out quota will still be considered."),
"hidden product or gain access to sold-out quota will still receive the discount."),
)
condition_min_count = models.PositiveIntegerField(
verbose_name=_('Minimum number of matching products'),
@@ -120,19 +120,6 @@ class Discount(LoggedModel):
default=Decimal('0.00'),
)
benefit_same_products = models.BooleanField(
default=True,
verbose_name=_("Apply discount to same set of products"),
help_text=_("By default, the discount is applied across the same selection of products than the condition for "
"the discount given above. If you want, you can however also select a different selection of "
"products.")
)
benefit_limit_products = models.ManyToManyField(
'Item',
verbose_name=_("Apply discount to specific products"),
related_name='benefit_discounts',
blank=True
)
benefit_discount_matching_percent = models.DecimalField(
verbose_name=_('Percentual discount on matching products'),
decimal_places=2,
@@ -152,18 +139,6 @@ class Discount(LoggedModel):
blank=True,
validators=[MinValueValidator(1)],
)
benefit_apply_to_addons = models.BooleanField(
default=True,
verbose_name=_("Apply to add-on products"),
help_text=_("Discounts never apply to bundled products"),
)
benefit_ignore_voucher_discounted = models.BooleanField(
default=False,
verbose_name=_("Ignore products discounted by a voucher"),
help_text=_("If this option is checked, products that already received a discount through a voucher will not "
"be discounted. However, products that use a voucher only to e.g. unlock a hidden product or gain "
"access to sold-out quota will still receive the discount."),
)
# more feature ideas:
# - max_usages_per_order
@@ -212,14 +187,6 @@ class Discount(LoggedModel):
'on a minimum value.')
)
if data.get('subevent_mode') == cls.SUBEVENT_MODE_DISTINCT and not data.get('benefit_same_products'):
raise ValidationError(
{'benefit_same_products': [
_('You cannot apply the discount to a different set of products if the discount is only valid '
'for bookings of different dates.')
]}
)
def allow_delete(self):
return not self.orderposition_set.exists()
@@ -230,7 +197,6 @@ class Discount(LoggedModel):
'condition_min_value': self.condition_min_value,
'benefit_only_apply_to_cheapest_n_matches': self.benefit_only_apply_to_cheapest_n_matches,
'subevent_mode': self.subevent_mode,
'benefit_same_products': self.benefit_same_products,
})
def is_available_by_time(self, now_dt=None) -> bool:
@@ -241,14 +207,14 @@ class Discount(LoggedModel):
return False
return True
def _apply_min_value(self, positions, condition_idx_group, benefit_idx_group, result):
if self.condition_min_value and sum(positions[idx][2] for idx in condition_idx_group) < self.condition_min_value:
def _apply_min_value(self, positions, idx_group, result):
if self.condition_min_value and sum(positions[idx][2] for idx in idx_group) < self.condition_min_value:
return
if self.condition_min_count or self.benefit_only_apply_to_cheapest_n_matches:
raise ValueError('Validation invariant violated.')
for idx in benefit_idx_group:
for idx in idx_group:
previous_price = positions[idx][2]
new_price = round_decimal(
previous_price * (Decimal('100.00') - self.benefit_discount_matching_percent) / Decimal('100.00'),
@@ -256,8 +222,8 @@ class Discount(LoggedModel):
)
result[idx] = new_price
def _apply_min_count(self, positions, condition_idx_group, benefit_idx_group, result):
if len(condition_idx_group) < self.condition_min_count:
def _apply_min_count(self, positions, idx_group, result):
if len(idx_group) < self.condition_min_count:
return
if not self.condition_min_count or self.condition_min_value:
@@ -267,17 +233,15 @@ class Discount(LoggedModel):
if not self.condition_min_count:
raise ValueError('Validation invariant violated.')
condition_idx_group = sorted(condition_idx_group, key=lambda idx: (positions[idx][2], -idx)) # sort by line_price
benefit_idx_group = sorted(benefit_idx_group, key=lambda idx: (positions[idx][2], -idx)) # sort by line_price
idx_group = sorted(idx_group, key=lambda idx: (positions[idx][2], -idx)) # sort by line_price
# Prevent over-consuming of items, i.e. if our discount is "buy 2, get 1 free", we only
# want to match multiples of 3
n_groups = min(len(condition_idx_group) // self.condition_min_count, len(benefit_idx_group))
consume_idx = condition_idx_group[:n_groups * self.condition_min_count]
benefit_idx = benefit_idx_group[:n_groups * self.benefit_only_apply_to_cheapest_n_matches]
consume_idx = idx_group[:len(idx_group) // self.condition_min_count * self.condition_min_count]
benefit_idx = idx_group[:len(idx_group) // self.condition_min_count * self.benefit_only_apply_to_cheapest_n_matches]
else:
consume_idx = condition_idx_group
benefit_idx = benefit_idx_group
consume_idx = idx_group
benefit_idx = idx_group
for idx in benefit_idx:
previous_price = positions[idx][2]
@@ -312,7 +276,7 @@ class Discount(LoggedModel):
limit_products = {p.pk for p in self.condition_limit_products.all()}
# First, filter out everything not even covered by our product scope
condition_candidates = [
initial_candidates = [
idx
for idx, (item_id, subevent_id, line_price_gross, is_addon_to, voucher_discount) in positions.items()
if (
@@ -322,25 +286,11 @@ class Discount(LoggedModel):
)
]
if self.benefit_same_products:
benefit_candidates = list(condition_candidates)
else:
benefit_products = {p.pk for p in self.benefit_limit_products.all()}
benefit_candidates = [
idx
for idx, (item_id, subevent_id, line_price_gross, is_addon_to, voucher_discount) in positions.items()
if (
item_id in benefit_products and
(self.benefit_apply_to_addons or not is_addon_to) and
(not self.benefit_ignore_voucher_discounted or voucher_discount is None or voucher_discount == Decimal('0.00'))
)
]
if self.subevent_mode == self.SUBEVENT_MODE_MIXED: # also applies to non-series events
if self.condition_min_count:
self._apply_min_count(positions, condition_candidates, benefit_candidates, result)
self._apply_min_count(positions, initial_candidates, result)
else:
self._apply_min_value(positions, condition_candidates, benefit_candidates, result)
self._apply_min_value(positions, initial_candidates, result)
elif self.subevent_mode == self.SUBEVENT_MODE_SAME:
def key(idx):
@@ -349,18 +299,17 @@ class Discount(LoggedModel):
# Build groups of candidates with the same subevent, then apply our regular algorithm
# to each group
_groups = groupby(sorted(condition_candidates, key=key), key=key)
candidate_groups = [(k, list(g)) for k, g in _groups]
_groups = groupby(sorted(initial_candidates, key=key), key=key)
candidate_groups = [list(g) for k, g in _groups]
for subevent_id, g in candidate_groups:
benefit_g = [idx for idx in benefit_candidates if positions[idx][1] == subevent_id]
for g in candidate_groups:
if self.condition_min_count:
self._apply_min_count(positions, g, benefit_g, result)
self._apply_min_count(positions, g, result)
else:
self._apply_min_value(positions, g, benefit_g, result)
self._apply_min_value(positions, g, result)
elif self.subevent_mode == self.SUBEVENT_MODE_DISTINCT:
if self.condition_min_value or not self.benefit_same_products:
if self.condition_min_value:
raise ValueError('Validation invariant violated.')
# Build optimal groups of candidates with distinct subevents, then apply our regular algorithm
@@ -387,7 +336,7 @@ class Discount(LoggedModel):
candidates = []
cardinality = None
for se, l in subevent_to_idx.items():
l = [ll for ll in l if ll in condition_candidates and ll not in current_group]
l = [ll for ll in l if ll in initial_candidates and ll not in current_group]
if cardinality and len(l) != cardinality:
continue
if se not in {positions[idx][1] for idx in current_group}:
@@ -424,5 +373,5 @@ class Discount(LoggedModel):
break
for g in candidate_groups:
self._apply_min_count(positions, g, g, result)
self._apply_min_count(positions, g, result)
return result
+2 -6
View File
@@ -907,18 +907,14 @@ class Event(EventMixin, LoggedModel):
self.items.filter(hidden_if_available_id=oldid).update(hidden_if_available=q)
for d in Discount.objects.filter(event=other).prefetch_related('condition_limit_products'):
c_items = list(d.condition_limit_products.all())
b_items = list(d.benefit_limit_products.all())
items = list(d.condition_limit_products.all())
d.pk = None
d.event = self
d.save(force_insert=True)
d.log_action('pretix.object.cloned')
for i in c_items:
for i in items:
if i.pk in item_map:
d.condition_limit_products.add(item_map[i.pk])
for i in b_items:
if i.pk in item_map:
d.benefit_limit_products.add(item_map[i.pk])
question_map = {}
for q in Question.objects.filter(event=other).prefetch_related('items', 'options'):
+4 -9
View File
@@ -43,7 +43,6 @@ from typing import Optional, Tuple
from zoneinfo import ZoneInfo
import dateutil.parser
import django_redis
from dateutil.tz import datetime_exists
from django.conf import settings
from django.core.exceptions import ValidationError
@@ -58,6 +57,7 @@ from django.utils.functional import cached_property
from django.utils.timezone import is_naive, make_aware, now
from django.utils.translation import gettext_lazy as _, pgettext_lazy
from django_countries.fields import Country
from django_redis import get_redis_connection
from django_scopes import ScopedManager
from i18nfield.fields import I18nCharField, I18nTextField
@@ -1463,7 +1463,7 @@ class Question(LoggedModel):
(TYPE_PHONENUMBER, _("Phone number")),
)
UNLOCALIZED_TYPES = [TYPE_DATE, TYPE_TIME, TYPE_DATETIME]
ASK_DURING_CHECKIN_UNSUPPORTED = []
ASK_DURING_CHECKIN_UNSUPPORTED = [TYPE_PHONENUMBER]
event = models.ForeignKey(
Event,
@@ -1910,13 +1910,8 @@ class Quota(LoggedModel):
def rebuild_cache(self, now_dt=None):
if settings.HAS_REDIS:
rc = django_redis.get_redis_connection("redis")
p = rc.pipeline()
p.hdel(f'quotas:{self.event_id}:availabilitycache', str(self.pk))
p.hdel(f'quotas:{self.event_id}:availabilitycache:nocw', str(self.pk))
p.hdel(f'quotas:{self.event_id}:availabilitycache:igcl', str(self.pk))
p.hdel(f'quotas:{self.event_id}:availabilitycache:nocw:igcl', str(self.pk))
p.execute()
rc = get_redis_connection("redis")
rc.hdel(f'quotas:{self.event_id}:availabilitycache', str(self.pk))
self.availability(now_dt=now_dt)
def availability(
+4 -11
View File
@@ -340,17 +340,10 @@ class TaxRule(LoggedModel):
rules = self._custom_rules
if invoice_address:
for r in rules:
if r['country'] == 'ZZ': # Rule: Any country
pass
elif r['country'] == 'EU': # Rule: Any EU country
if not is_eu_country(invoice_address.country):
continue
elif '-' in r['country']: # Rule: Specific country and state
if r['country'] != str(invoice_address.country) + '-' + str(invoice_address.state):
continue
else: # Rule: Specific country
if r['country'] != str(invoice_address.country):
continue
if r['country'] == 'EU' and not is_eu_country(invoice_address.country):
continue
if r['country'] not in ('ZZ', 'EU') and r['country'] != str(invoice_address.country):
continue
if r['address_type'] == 'individual' and invoice_address.is_business:
continue
if r['address_type'] in ('business', 'business_vat_id') and not invoice_address.is_business:
+1 -1
View File
@@ -742,7 +742,7 @@ class BasePaymentProvider:
the amount of money that should be paid.
If you need any special behavior, you can return a string containing the URL the user will be redirected to.
If you are done with your process you should return the user to the order's detail page. Redirection is only
If you are done with your process you should return the user to the order's detail page. Redirection is not
allowed if you set ``execute_payment_needs_user`` to ``True``.
If the payment is completed, you should call ``payment.confirm()``. Please note that this might
+3 -6
View File
@@ -108,10 +108,7 @@ DEFAULT_VARIABLES = OrderedDict((
("positionid", {
"label": _("Order position number"),
"editor_sample": "1",
"evaluate": lambda orderposition, order, event: str(orderposition.positionid),
# There is no performance gain in using evaluate_bulk here, but we want to make sure it is used somewhere
# in core to make sure we notice if the implementation of the API breaks.
"evaluate_bulk": lambda orderpositions: [str(p.positionid) for p in orderpositions],
"evaluate": lambda orderposition, order, event: str(orderposition.positionid)
}),
("order_positionid", {
"label": _("Order code and position number"),
@@ -702,10 +699,10 @@ def get_seat(op: OrderPosition):
def generate_compressed_addon_list(op, order, event):
itemcount = defaultdict(int)
addons = [p for p in (
addons = (
op.addons.all() if 'addons' in getattr(op, '_prefetched_objects_cache', {})
else op.addons.select_related('item', 'variation')
) if not p.canceled]
)
for pos in addons:
itemcount[pos.item, pos.variation] += 1
+8 -20
View File
@@ -1078,7 +1078,6 @@ class CartManager:
quotas_ok = _get_quota_availability(self._quota_diff, self.now_dt)
err = None
new_cart_positions = []
deleted_positions = set()
err = err or self._check_min_max_per_product()
@@ -1090,10 +1089,7 @@ class CartManager:
if op.position.expires > self.now_dt:
for q in op.position.quotas:
quotas_ok[q] += 1
addons = op.position.addons.all()
deleted_positions |= {a.pk for a in addons}
addons.delete()
deleted_positions.add(op.position.pk)
op.position.addons.all().delete()
op.position.delete()
elif isinstance(op, (self.AddOperation, self.ExtendOperation)):
@@ -1243,28 +1239,20 @@ class CartManager:
if op.seat and not op.seat.is_available(ignore_cart=op.position, sales_channel=self._sales_channel,
ignore_voucher_id=op.position.voucher_id):
err = err or error_messages['seat_unavailable']
addons = op.position.addons.all()
deleted_positions |= {a.pk for a in addons}
deleted_positions.add(op.position.pk)
addons.delete()
op.position.addons.all().delete()
op.position.delete()
elif available_count == 1:
op.position.expires = self._expiry
op.position.listed_price = op.listed_price
op.position.price_after_voucher = op.price_after_voucher
# op.position.price will be updated by recompute_final_prices_and_taxes()
if op.position.pk not in deleted_positions:
try:
op.position.save(force_update=True, update_fields=['expires', 'listed_price', 'price_after_voucher'])
except DatabaseError:
# Best effort... The position might have been deleted in the meantime!
pass
try:
op.position.save(force_update=True, update_fields=['expires', 'listed_price', 'price_after_voucher'])
except DatabaseError:
# Best effort... The position might have been deleted in the meantime!
pass
elif available_count == 0:
addons = op.position.addons.all()
deleted_positions |= {a.pk for a in addons}
deleted_positions.add(op.position.pk)
addons.delete()
op.position.addons.all().delete()
op.position.delete()
else:
raise AssertionError("ExtendOperation cannot affect more than one item")
+4 -4
View File
@@ -773,7 +773,7 @@ def perform_checkin(op: OrderPosition, clist: CheckinList, given_answers: dict,
'blocked'
)
if type != Checkin.TYPE_EXIT and op.valid_from and op.valid_from > dt:
if type not in (Checkin.TYPE_PRINT, Checkin.TYPE_EXIT) and op.valid_from and op.valid_from > dt:
if force:
force_used = True
else:
@@ -787,7 +787,7 @@ def perform_checkin(op: OrderPosition, clist: CheckinList, given_answers: dict,
),
)
if type != Checkin.TYPE_EXIT and op.valid_until and op.valid_until < dt:
if type not in (Checkin.TYPE_PRINT, Checkin.TYPE_EXIT) and op.valid_until and op.valid_until < dt:
if force:
force_used = True
else:
@@ -886,9 +886,9 @@ def perform_checkin(op: OrderPosition, clist: CheckinList, given_answers: dict,
if isinstance(auth, Device):
device = auth
last_cis = list(op.checkins.order_by('-datetime').filter(list=clist).only('type', 'nonce', 'position_id'))
last_cis = list(op.checkins.order_by('-datetime').filter(list=clist, type__in=(Checkin.TYPE_ENTRY, Checkin.TYPE_EXIT)).only('type', 'nonce'))
entry_allowed = (
type == Checkin.TYPE_EXIT or
type in (Checkin.TYPE_EXIT, Checkin.TYPE_PRINT) or
clist.allow_multiple_entries or
not last_cis or
all(c.type == Checkin.TYPE_EXIT for c in last_cis) or
+1 -1
View File
@@ -171,7 +171,7 @@ def apply_discounts(event: Event, sales_channel: str,
Q(available_until__isnull=True) | Q(available_until__gte=now()),
sales_channels__contains=sales_channel,
active=True,
).prefetch_related('condition_limit_products', 'benefit_limit_products').order_by('position', 'pk')
).prefetch_related('condition_limit_products').order_by('position', 'pk')
for discount in discount_qs:
result = discount.apply({
idx: (item_id, subevent_id, line_price_gross, is_addon_to, voucher_discount)
+12 -15
View File
@@ -24,13 +24,13 @@ import time
from collections import Counter, defaultdict
from itertools import zip_longest
import django_redis
from django.conf import settings
from django.db import models
from django.db.models import (
Case, Count, F, Func, Max, OuterRef, Q, Subquery, Sum, Value, When,
)
from django.utils.timezone import now
from django_redis import get_redis_connection
from pretix.base.models import (
CartPosition, Checkin, Order, OrderPosition, Quota, Voucher,
@@ -102,12 +102,6 @@ class QuotaAvailability:
self.count_waitinglist = defaultdict(int)
self.count_cart = defaultdict(int)
self._cache_key_suffix = ""
if not self._count_waitinglist:
self._cache_key_suffix += ":nocw"
if self._ignore_closed:
self._cache_key_suffix += ":igcl"
self.sizes = {}
def queue(self, *quota):
@@ -127,14 +121,17 @@ class QuotaAvailability:
if self._full_results:
raise ValueError("You cannot combine full_results and allow_cache.")
elif not self._count_waitinglist:
raise ValueError("If you set allow_cache, you need to set count_waitinglist.")
elif settings.HAS_REDIS:
rc = django_redis.get_redis_connection("redis")
rc = get_redis_connection("redis")
quotas_by_event = defaultdict(list)
for q in [_q for _q in self._queue if _q.id in quota_ids_set]:
quotas_by_event[q.event_id].append(q)
for eventid, evquotas in quotas_by_event.items():
d = rc.hmget(f'quotas:{eventid}:availabilitycache{self._cache_key_suffix}', [str(q.pk) for q in evquotas])
d = rc.hmget(f'quotas:{eventid}:availabilitycache', [str(q.pk) for q in evquotas])
for redisval, q in zip(d, evquotas):
if redisval is not None:
data = [rv for rv in redisval.decode().split(',')]
@@ -167,12 +164,12 @@ class QuotaAvailability:
if not settings.HAS_REDIS or not quotas:
return
rc = django_redis.get_redis_connection("redis")
rc = get_redis_connection("redis")
# We write the computed availability to redis in a per-event hash as
#
# quota_id -> (availability_state, availability_number, timestamp).
#
# We store this in a hash instead of individual values to avoid making too many redis requests
# We store this in a hash instead of inidividual values to avoid making two many redis requests
# which would introduce latency.
# The individual entries in the hash are "valid" for 120 seconds. This means in a typical peak scenario with
@@ -182,16 +179,16 @@ class QuotaAvailability:
# these quotas. We choose 10 seconds since that should be well above the duration of a write.
lock_name = '_'.join([str(p) for p in sorted([q.pk for q in quotas])])
if rc.exists(f'quotas:availabilitycachewrite:{lock_name}{self._cache_key_suffix}'):
if rc.exists(f'quotas:availabilitycachewrite:{lock_name}'):
return
rc.setex(f'quotas:availabilitycachewrite:{lock_name}{self._cache_key_suffix}', '1', 10)
rc.setex(f'quotas:availabilitycachewrite:{lock_name}', '1', 10)
update = defaultdict(list)
for q in quotas:
update[q.event_id].append(q)
for eventid, quotas in update.items():
rc.hmset(f'quotas:{eventid}:availabilitycache{self._cache_key_suffix}', {
rc.hmset(f'quotas:{eventid}:availabilitycache', {
str(q.id): ",".join(
[str(i) for i in self.results[q]] +
[str(int(time.time()))]
@@ -200,7 +197,7 @@ class QuotaAvailability:
# To make sure old events do not fill up our redis instance, we set an expiry on the cache. However, we set it
# on 7 days even though we mostly ignore values older than 2 monites. The reasoning is that we have some places
# where we set allow_cache_stale and use the old entries anyways to save on performance.
rc.expire(f'quotas:{eventid}:availabilitycache{self._cache_key_suffix}', 3600 * 24 * 7)
rc.expire(f'quotas:{eventid}:availabilitycache', 3600 * 24 * 7)
# We used to also delete item_quota_cache:* from the event cache here, but as the cache
# gets more complex, this does not seem worth it. The cache is only present for up to
+4 -19
View File
@@ -22,15 +22,13 @@
import sys
from datetime import timedelta
from django.db.models import (
Exists, F, OuterRef, Prefetch, Q, Sum, prefetch_related_objects,
)
from django.db.models import Exists, F, OuterRef, Q, Sum
from django.dispatch import receiver
from django.utils.timezone import now
from django_scopes import scopes_disabled
from pretix.base.models import (
Event, EventMetaValue, SeatCategoryMapping, User, WaitingListEntry,
Event, SeatCategoryMapping, User, WaitingListEntry,
)
from pretix.base.models.waitinglist import WaitingListException
from pretix.base.services.tasks import EventTask
@@ -61,21 +59,8 @@ def assign_automatically(event: Event, user_id: int=None, subevent_id: int=None)
).aggregate(free=Sum(F('max_usages') - F('redeemed')))['free'] or 0
seats_available[(m.product_id, m.subevent_id)] = num_free_seets_for_product - num_valid_vouchers_for_product
prefetch_related_objects(
[event.organizer],
'meta_properties'
)
prefetch_related_objects(
[event],
Prefetch(
'meta_values',
EventMetaValue.objects.select_related('property'),
to_attr='meta_values_cached'
)
)
qs = event.waitinglistentries.filter(
voucher__isnull=True
qs = WaitingListEntry.objects.filter(
event=event, voucher__isnull=True
).select_related('item', 'variation', 'subevent').prefetch_related(
'item__quotas', 'variation__quotas'
).order_by('-priority', 'created')
-2
View File
@@ -210,8 +210,6 @@ def slow_delete(qs, batch_size=1000, sleep_time=.5, progress_callback=None, prog
break
if total_deleted >= 0.8 * batch_size:
time.sleep(sleep_time)
if progress_callback and progress_total:
progress_callback((progress_offset + total_deleted) / progress_total)
return total_deleted
+3 -3
View File
@@ -292,7 +292,7 @@ class LinkifyAndCleanExtension(Extension):
)
def markdown_compile_email(source, allowed_tags=ALLOWED_TAGS, allowed_attributes=ALLOWED_ATTRIBUTES):
def markdown_compile_email(source):
linker = bleach.Linker(
url_re=URL_RE,
email_re=EMAIL_RE,
@@ -306,8 +306,8 @@ def markdown_compile_email(source, allowed_tags=ALLOWED_TAGS, allowed_attributes
EmailNl2BrExtension(),
LinkifyAndCleanExtension(
linker,
tags=allowed_tags,
attributes=allowed_attributes,
tags=ALLOWED_TAGS,
attributes=ALLOWED_ATTRIBUTES,
protocols=ALLOWED_PROTOCOLS,
strip=False,
)
+1 -10
View File
@@ -50,16 +50,11 @@ class DiscountForm(I18nModelForm):
'condition_ignore_voucher_discounted',
'benefit_discount_matching_percent',
'benefit_only_apply_to_cheapest_n_matches',
'benefit_same_products',
'benefit_limit_products',
'benefit_apply_to_addons',
'benefit_ignore_voucher_discounted',
]
field_classes = {
'available_from': SplitDateTimeField,
'available_until': SplitDateTimeField,
'condition_limit_products': ItemMultipleChoiceField,
'benefit_limit_products': ItemMultipleChoiceField,
}
widgets = {
'subevent_mode': forms.RadioSelect,
@@ -69,14 +64,11 @@ class DiscountForm(I18nModelForm):
'data-inverse-dependency': '<[name$=all_products]',
'class': 'scrolling-multiple-choice',
}),
'benefit_limit_products': forms.CheckboxSelectMultiple(attrs={
'class': 'scrolling-multiple-choice',
}),
'benefit_only_apply_to_cheapest_n_matches': forms.NumberInput(
attrs={
'data-display-dependency': '#id_condition_min_count',
}
),
)
}
def __init__(self, *args, **kwargs):
@@ -93,7 +85,6 @@ class DiscountForm(I18nModelForm):
widget=forms.CheckboxSelectMultiple,
)
self.fields['condition_limit_products'].queryset = self.event.items.all()
self.fields['benefit_limit_products'].queryset = self.event.items.all()
self.fields['condition_min_count'].required = False
self.fields['condition_min_count'].widget.is_required = False
self.fields['condition_min_value'].required = False
+2 -15
View File
@@ -38,7 +38,6 @@ from decimal import Decimal
from urllib.parse import urlencode, urlparse
from zoneinfo import ZoneInfo
import pycountry
from django import forms
from django.conf import settings
from django.core.exceptions import NON_FIELD_ERRORS, ValidationError
@@ -66,8 +65,7 @@ from pretix.base.models import Event, Organizer, TaxRule, Team
from pretix.base.models.event import EventFooterLink, EventMetaValue, SubEvent
from pretix.base.reldate import RelativeDateField, RelativeDateTimeField
from pretix.base.settings import (
COUNTRIES_WITH_STATE_IN_ADDRESS, PERSON_NAME_SCHEMES,
PERSON_NAME_TITLE_GROUPS, validate_event_settings,
PERSON_NAME_SCHEMES, PERSON_NAME_TITLE_GROUPS, validate_event_settings,
)
from pretix.base.validators import multimail_validate
from pretix.control.forms import (
@@ -1430,20 +1428,9 @@ class CountriesAndEU(CachedCountries):
cache_subkey = 'with_any_or_eu'
class CountriesAndEUAndStates(CountriesAndEU):
def __iter__(self):
for country_code, country_name in super().__iter__():
yield country_code, country_name
if country_code in COUNTRIES_WITH_STATE_IN_ADDRESS:
types, form = COUNTRIES_WITH_STATE_IN_ADDRESS[country_code]
yield from sorted(((state.code, country_name + " - " + state.name)
for state in pycountry.subdivisions.get(country_code=country_code)
if state.type in types), key=lambda s: s[1])
class TaxRuleLineForm(I18nForm):
country = LazyTypedChoiceField(
choices=CountriesAndEUAndStates(),
choices=CountriesAndEU(),
required=False
)
address_type = forms.ChoiceField(
+2 -2
View File
@@ -1732,8 +1732,8 @@ class CheckinListAttendeeFilterForm(FilterForm):
'-timestamp': (OrderBy(F('last_entry'), nulls_last=True, descending=True), '-order__code'),
'item': ('item__name', 'variation__value', 'order__code'),
'-item': ('-item__name', '-variation__value', '-order__code'),
'seat': ('seat__sorting_rank', 'seat__seat_guid'),
'-seat': ('-seat__sorting_rank', '-seat__seat_guid'),
'seat': ('seat__sorting_rank', 'seat__guid'),
'-seat': ('-seat__sorting_rank', '-seat__guid'),
'date': ('subevent__date_from', 'subevent__id', 'order__code'),
'-date': ('-subevent__date_from', 'subevent__id', '-order__code'),
'name': {'_order': F('display_name').asc(nulls_first=True),
+2 -4
View File
@@ -86,14 +86,12 @@ class GlobalSettingsForm(SettingsForm):
('leaflet_tiles', forms.CharField(
required=False,
label=_("Leaflet tiles URL pattern"),
help_text=_("e.g. {sample}").format(sample="https://tile.openstreetmap.org/{z}/{x}/{y}.png")
help_text=_("e.g. {sample}").format(sample="https://a.tile.openstreetmap.org/{z}/{x}/{y}.png")
)),
('leaflet_tiles_attribution', forms.CharField(
required=False,
label=_("Leaflet tiles attribution"),
help_text=_("e.g. {sample}").format(
sample='&copy; &lt;a href=&quot;https://www.openstreetmap.org/copyright&quot;&gt;OpenStreetMap&lt;/a&gt; contributors'
)
help_text=_("e.g. {sample}").format(sample='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors')
)),
])
responses = register_global_settings.send(self)
+5
View File
@@ -461,6 +461,11 @@ class ItemCreateForm(I18nModelForm):
)
if self.cleaned_data.get('copy_from'):
for mv in self.cleaned_data['copy_from'].meta_values.all():
mv.pk = None
mv.item = instance
mv.save(force_insert=True)
for question in self.cleaned_data['copy_from'].questions.all():
question.items.add(instance)
question.log_action('pretix.event.question.changed', user=self.user, data={
-3
View File
@@ -340,9 +340,6 @@ class VoucherBulkForm(VoucherForm):
def clean_send_recipients(self):
raw = self.cleaned_data['send_recipients']
if self.cleaned_data.get('send', None) is False:
# No need to validate addresses if the section was turned off
return []
if not raw:
return []
r = raw.split('\n')
+14
View File
@@ -295,6 +295,20 @@ def _display_checkin(event, logentry):
posid=data.get('positionid'),
list=checkin_list
)
if data.get('type') == Checkin.TYPE_PRINT:
if show_dt:
return _('Position #{posid} has been printed out at {datetime} for list "{list}".').format(
posid=data.get('positionid'),
datetime=dt_formatted,
list=checkin_list
)
else:
return _('Position #{posid} has been printed out for list "{list}".').format(
posid=data.get('positionid'),
list=checkin_list
)
if data.get('first'):
if show_dt:
return _('Position #{posid} has been checked in at {datetime} for list "{list}".').format(
@@ -95,6 +95,7 @@
<td>
{% if c.type == "exit" %}<span class="fa fa-fw fa-sign-out"></span>{% endif %}
{% if c.type == "entry" %}<span class="fa fa-fw fa-sign-in"></span>{% endif %}
{% if c.type == "print" %}<span class="fa fa-fw fa-print"></span>{% endif %}
{{ c.get_type_display }}
<br>
<small>
@@ -1,27 +0,0 @@
{% load i18n %}
<ul class="dropdown-menu dropdown-menu-right">
<li>
<a href="{% url "control:event.qrcode" event=request.event.slug organizer=request.organizer.slug filetype="png" %}{% if url %}?url={{ url|urlencode }}{% endif %}"
target="_blank" download>
{% blocktrans with filetype="PNG" %}Download QR code as {{ filetype }} image{% endblocktrans %}
</a>
</li>
<li>
<a href="{% url "control:event.qrcode" event=request.event.slug organizer=request.organizer.slug filetype="svg" %}{% if url %}?url={{ url|urlencode }}{% endif %}"
target="_blank" download>
{% blocktrans with filetype="SVG" %}Download QR code as {{ filetype }} image{% endblocktrans %}
</a>
</li>
<li>
<a href="{% url "control:event.qrcode" event=request.event.slug organizer=request.organizer.slug filetype="jpeg" %}{% if url %}?url={{ url|urlencode }}{% endif %}"
target="_blank" download>
{% blocktrans with filetype="JPG" %}Download QR code as {{ filetype }} image{% endblocktrans %}
</a>
</li>
<li>
<a href="{% url "control:event.qrcode" event=request.event.slug organizer=request.organizer.slug filetype="gif" %}{% if url %}?url={{ url|urlencode }}{% endif %}"
target="_blank" download>
{% blocktrans with filetype="GIF" %}Download QR code as {{ filetype }} image{% endblocktrans %}
</a>
</li>
</ul>
@@ -27,7 +27,28 @@
<button type="button" class="btn btn-default btn-xs dropdown-toggle" data-toggle="dropdown" title="{% trans "Create QR code" %}" aria-haspopup="true" aria-expanded="false">
<i class="fa fa-qrcode" aria-hidden="true"></i>
</button>
{% include "pretixcontrol/event/fragment_qr_dropdown.html" with url=0 %}
<ul class="dropdown-menu dropdown-menu-right">
<li>
<a href="{% url "control:event.qrcode" event=request.event.slug organizer=request.organizer.slug filetype="png" %}" target="_blank" download>
{% blocktrans with filetype="PNG" %}Download QR code as {{ filetype }} image{% endblocktrans %}
</a>
</li>
<li>
<a href="{% url "control:event.qrcode" event=request.event.slug organizer=request.organizer.slug filetype="svg" %}" target="_blank" download>
{% blocktrans with filetype="SVG" %}Download QR code as {{ filetype }} image{% endblocktrans %}
</a>
</li>
<li>
<a href="{% url "control:event.qrcode" event=request.event.slug organizer=request.organizer.slug filetype="jpeg" %}" target="_blank" download>
{% blocktrans with filetype="JPG" %}Download QR code as {{ filetype }} image{% endblocktrans %}
</a>
</li>
<li>
<a href="{% url "control:event.qrcode" event=request.event.slug organizer=request.organizer.slug filetype="gif" %}" target="_blank" download>
{% blocktrans with filetype="GIF" %}Download QR code as {{ filetype }} image{% endblocktrans %}
</a>
</li>
</ul>
</div>
<div class="clearfix"></div>
</div>
@@ -337,7 +337,7 @@
<div class="alert alert-info">
{% blocktrans trimmed %}
The waiting list currently is not compatible with some advanced features of pretix such as
hidden products, add-on products or product bundles.
add-on products or product bundles.
{% endblocktrans %}
</div>
<div class="alert alert-info">
@@ -48,12 +48,6 @@
</fieldset>
<fieldset>
<legend>{% trans "Benefit" context "discount" %}</legend>
{% bootstrap_field form.benefit_same_products layout="control" %}
<div data-display-dependency="#id_benefit_same_products" data-inverse>
{% bootstrap_field form.benefit_limit_products layout="control" %}
{% bootstrap_field form.benefit_apply_to_addons layout="control" %}
{% bootstrap_field form.benefit_ignore_voucher_discounted layout="control" %}
</div>
{% bootstrap_field form.benefit_discount_matching_percent layout="control" addon_after="%" %}
{% bootstrap_field form.benefit_only_apply_to_cheapest_n_matches layout="control" %}
</fieldset>
@@ -385,6 +385,8 @@
{% else %}
<span class="fa fa-fw text-success fa-sign-out" data-toggle="tooltip_html" title="{{ c.list.name|force_escape|force_escape }}<br>{% blocktrans trimmed with date=c.datetime|date:'SHORT_DATETIME_FORMAT' %}Exit scan: {{ date }}{% endblocktrans %}{% if c.gate %}<br>{{ c.gate }}{% endif %}"></span>
{% endif %}
{% elif c.type == "print" %}
<span class="fa fa-fw text-success fa-print" data-toggle="tooltip_html" title="{{ c.list.name|force_escape|force_escape }}<br>{% blocktrans trimmed with date=c.datetime|date:'SHORT_DATETIME_FORMAT' %}Print scan: {{ date }}{% endblocktrans %}{% if c.gate %}<br>{{ c.gate }}{% endif %}"></span>
{% elif c.forced %}
<span class="fa fa-fw fa-warning text-warning" data-toggle="tooltip_html" title="{{ c.list.name|force_escape|force_escape }}<br>{% blocktrans trimmed with date=c.datetime|date:'SHORT_DATETIME_FORMAT' %}Additional entry scan: {{ date }}{% endblocktrans %}{% if c.gate %}<br>{{ c.gate }}{% endif %}"></span>
{% elif c.auto_checked_in %}
@@ -42,18 +42,10 @@
<div class="form-group">
<label class="col-md-3 control-label" for="id_url">{% trans "Voucher link" %}</label>
<div class="col-md-9">
<div class="input-group">
<input type="text" name="url"
value="{{ url }}"
class="form-control"
id="id_url" readonly>
<div class="input-group-btn">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" title="{% trans "Create QR code" %}" aria-haspopup="true" aria-expanded="false">
<i class="fa fa-qrcode" aria-hidden="true"></i>
</button>
{% include "pretixcontrol/event/fragment_qr_dropdown.html" with url=url %}
</div>
</div>
<input type="text" name="url"
value="{% abseventurl request.event "presale:event.redeem" %}?voucher={{ voucher.code|urlencode }}{% if voucher.subevent_id %}&subevent={{ voucher.subevent_id }}{% endif %}"
class="form-control"
id="id_url" readonly>
</div>
</div>
{% endif %}
@@ -96,9 +96,7 @@
<tr>
<th>
{% if "can_change_vouchers" in request.eventpermset %}
<label aria-label="{% trans "select all rows for batch-operation" %}" class="batch-select-label">
<input type="checkbox" data-toggle-table />
</label>
<input type="checkbox" data-toggle-table />
{% endif %}
</th>
<th>
@@ -141,9 +139,7 @@
<tr>
<td>
{% if "can_change_vouchers" in request.eventpermset %}
<label aria-label="{% trans "select row for batch-operation" %}" class="batch-select-label">
<input type="checkbox" name="voucher" class="batch-select-checkbox" value="{{ v.pk }}"/>
</label>
<input type="checkbox" name="voucher" class="" value="{{ v.pk }}"/>
{% endif %}
</td>
<td>
@@ -198,12 +194,9 @@
</table>
</div>
{% if "can_change_vouchers" in request.eventpermset %}
<div class="batch-select-actions">
<button type="submit" class="btn btn-danger" name="action" value="delete">
<i class="fa fa-trash" aria-hidden="true"></i>
{% trans "Delete selected" %}
</button>
</div>
<button type="submit" class="btn btn-default btn-save" name="action" value="delete">
{% trans "Delete selected" %}
</button>
{% endif %}
</form>
{% include "pretixcontrol/pagination.html" %}
+3 -3
View File
@@ -198,12 +198,12 @@ def waitinglist_widgets(sender, subevent=None, lazy=False, **kwargs):
else item.check_quotas(subevent=subevent, count_waitinglist=False, _cache=quota_cache)
)
if row[1] is None:
happy += wlt['cnt']
happy += 1
elif row[1] > 0:
happy += min(wlt['cnt'], row[1])
happy += 1
for q in quotas:
if q.size is not None:
quota_cache[q.pk] = (quota_cache[q.pk][0], quota_cache[q.pk][1] - min(wlt['cnt'], row[1]))
quota_cache[q.pk] = (quota_cache[q.pk][0], quota_cache[q.pk][1] - 1)
widgets.append({
'content': None if lazy else NUM_WIDGET.format(
+3 -11
View File
@@ -40,7 +40,7 @@ from collections import OrderedDict
from decimal import Decimal
from io import BytesIO
from itertools import groupby
from urllib.parse import urlparse, urlsplit
from urllib.parse import urlsplit
from zoneinfo import ZoneInfo
import bleach
@@ -50,7 +50,6 @@ from django.apps import apps
from django.conf import settings
from django.contrib import messages
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import PermissionDenied
from django.core.files import File
from django.db import transaction
from django.db.models import ProtectedError
@@ -62,7 +61,6 @@ from django.http import (
from django.shortcuts import get_object_or_404, redirect
from django.urls import reverse
from django.utils.functional import cached_property
from django.utils.http import url_has_allowed_host_and_scheme
from django.utils.timezone import now
from django.utils.translation import gettext, gettext_lazy as _, gettext_noop
from django.views.generic import FormView, ListView
@@ -785,8 +783,8 @@ class MailSettingsRendererPreview(MailSettingsPreview):
return ctx
def get(self, request, *args, **kwargs):
v = str(request.event.settings.mail_text_order_placed)
v = format_map(v, self.placeholders('mail_text_order_placed'))
v = str(request.event.settings.mail_text_order_payment_failed)
v = format_map(v, self.placeholders('mail_text_order_payment_failed'))
renderers = request.event.get_html_mail_renderers()
if request.GET.get('renderer') in renderers:
with rolledback_transaction():
@@ -1532,12 +1530,6 @@ class EventQRCode(EventPermissionRequiredMixin, View):
def get(self, request, *args, filetype, **kwargs):
url = build_absolute_uri(request.event, 'presale:event.index')
if "url" in request.GET:
if url_has_allowed_host_and_scheme(request.GET["url"], allowed_hosts=[urlparse(url).netloc]):
url = request.GET["url"]
else:
raise PermissionDenied("Untrusted URL")
qr = qrcode.QRCode(
version=1,
error_correction=qrcode.constants.ERROR_CORRECT_M,
+4 -29
View File
@@ -1188,46 +1188,30 @@ class MetaDataEditorMixin:
@cached_property
def meta_forms(self):
if getattr(self, 'object', None):
if hasattr(self, 'object') and self.object:
val_instances = {
v.property_id: v for v in self.object.meta_values.all()
}
else:
val_instances = {}
if getattr(self, 'copy_from', None):
defaults = {
v.property_id: v.value for v in self.copy_from.meta_values.all()
}
else:
defaults = {}
formlist = []
for p in self.request.event.item_meta_properties.all():
formlist.append(self._make_meta_form(p, val_instances, defaults))
formlist.append(self._make_meta_form(p, val_instances))
return formlist
def _make_meta_form(self, p, val_instances, defaults):
def _make_meta_form(self, p, val_instances):
return self.meta_form(
prefix='prop-{}'.format(p.pk),
property=p,
instance=val_instances.get(
p.pk,
self.meta_model(
property=p,
item=self.object if getattr(self, 'object', None) else None,
value=defaults.get(p.pk, None)
)
),
instance=val_instances.get(p.pk, self.meta_model(property=p, item=self.object)),
data=(self.request.POST if self.request.method == "POST" else None)
)
def save_meta(self):
for f in self.meta_forms:
if f.cleaned_data.get('value'):
if not f.instance.item_id:
f.instance.item = self.object
f.save()
elif f.instance and f.instance.pk:
f.instance.delete()
@@ -1273,7 +1257,6 @@ class ItemCreate(EventPermissionRequiredMixin, MetaDataEditorMixin, CreateView):
messages.success(self.request, _('Your changes have been saved.'))
ret = super().form_valid(form)
self.save_meta()
form.instance.log_action('pretix.event.item.added', user=self.request.user, data={
k: (form.cleaned_data.get(k).name
if isinstance(form.cleaned_data.get(k), File)
@@ -1300,14 +1283,6 @@ class ItemCreate(EventPermissionRequiredMixin, MetaDataEditorMixin, CreateView):
ctx['meta_forms'] = self.meta_forms
return ctx
def post(self, request, *args, **kwargs):
self.object = None
form = self.get_form()
if form.is_valid() and all([f.is_valid() for f in self.meta_forms]):
return self.form_valid(form)
else:
return self.form_invalid(form)
class ItemUpdateGeneral(ItemDetailMixin, EventPermissionRequiredMixin, MetaDataEditorMixin, UpdateView):
form_class = ItemUpdateForm
+2 -2
View File
@@ -1054,8 +1054,8 @@ class DeviceBulkUpdateView(DeviceQueryMixin, OrganizerDetailViewMixin, Organizer
limit_events_list=Subquery(
Device.limit_events.through.objects.filter(
device_id=OuterRef('pk')
).order_by().values('device_id').annotate(
g=GroupConcat('event_id', separator=',', ordered=True)
).order_by('device_id', 'event_id').values('device_id').annotate(
g=GroupConcat('event_id', separator=',')
).values('g')
)
)
+1 -1
View File
@@ -546,7 +546,7 @@ def variations_select2(request, **kwargs):
F('item__category__position').asc(nulls_first=True),
'item__category_id',
'item__position',
'item__pk',
'item__pk'
'position',
'value'
).select_related('item')
-9
View File
@@ -34,7 +34,6 @@
# License for the specific language governing permissions and limitations under the License.
import io
from urllib.parse import urlencode
import bleach
from defusedcsv import csv
@@ -76,7 +75,6 @@ from pretix.control.views import PaginationMixin
from pretix.helpers.compat import CompatDeleteView
from pretix.helpers.format import format_map
from pretix.helpers.models import modelcopy
from pretix.multidomain.urlreverse import build_absolute_uri
class VoucherList(PaginationMixin, EventPermissionRequiredMixin, ListView):
@@ -317,13 +315,6 @@ class VoucherUpdate(EventPermissionRequiredMixin, UpdateView):
expires__gte=now()
).count()
ctx['redeemed_in_carts'] = redeemed_in_carts
url_params = {
'voucher': self.object.code
}
if self.object.subevent_id:
url_params['subevent'] = self.object.subevent_id
ctx['url'] = build_absolute_uri(self.request.event, "presale:event.redeem") + "?" + urlencode(url_params)
return ctx
+6 -14
View File
@@ -66,26 +66,18 @@ class GroupConcat(Aggregate):
function = 'group_concat'
template = '%(function)s(%(field)s, "%(separator)s")'
def __init__(self, *expressions, ordered=False, **extra):
self.ordered = ordered
def __init__(self, *expressions, **extra):
if 'separator' not in extra:
# For PostgreSQL separator is an obligatory
extra.update({'separator': ','})
super().__init__(*expressions, **extra)
def as_postgresql(self, compiler, connection):
if self.ordered:
return super().as_sql(
compiler, connection,
function='string_agg',
template="%(function)s(%(field)s::text, '%(separator)s' ORDER BY %(field)s ASC)",
)
else:
return super().as_sql(
compiler, connection,
function='string_agg',
template="%(function)s(%(field)s::text, '%(separator)s')",
)
return super().as_sql(
compiler, connection,
function='string_agg',
template="%(function)s(%(field)s::text, '%(separator)s')",
)
class ReplicaRouter:
+3 -3
View File
@@ -24799,7 +24799,7 @@ msgstr[0] ""
msgstr[1] ""
#: pretix/plugins/sendmail/signals.py:99
msgid "Scheduled emails"
msgid "Automated emails"
msgstr ""
#: pretix/plugins/sendmail/signals.py:122
@@ -24877,7 +24877,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:14
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:15
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:10
msgid "Scheduled emails are not sent as long as your ticket shop is offline."
msgid "Automated emails are not sent as long as your ticket shop is offline."
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:44
@@ -24924,7 +24924,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:4
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:6
msgid "Scheduled email rules"
msgid "Automated email rules"
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:8
+3 -3
View File
@@ -28366,7 +28366,7 @@ msgstr[5] ""
#: pretix/plugins/sendmail/signals.py:99
#, fuzzy
#| msgid "Attendee email"
msgid "Scheduled emails"
msgid "Automated emails"
msgstr "البريد الإلكتروني للحاضر"
#: pretix/plugins/sendmail/signals.py:122
@@ -28460,7 +28460,7 @@ msgstr "إنشاء مستخدم جديد"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:14
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:15
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:10
msgid "Scheduled emails are not sent as long as your ticket shop is offline."
msgid "Automated emails are not sent as long as your ticket shop is offline."
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:44
@@ -28523,7 +28523,7 @@ msgstr "اختيار البيانات"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:6
#, fuzzy
#| msgid "Attendee e-mail address"
msgid "Scheduled email rules"
msgid "Automated email rules"
msgstr "عنوان البريد الإلكتروني للحاضر"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:8
+3 -3
View File
@@ -28023,7 +28023,7 @@ msgstr[1] ""
#: pretix/plugins/sendmail/signals.py:99
#, fuzzy
#| msgid "Attendee email"
msgid "Scheduled emails"
msgid "Automated emails"
msgstr "Correu electrònic de l'assistent"
#: pretix/plugins/sendmail/signals.py:122
@@ -28119,7 +28119,7 @@ msgstr "Crear un nou usuari"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:14
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:15
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:10
msgid "Scheduled emails are not sent as long as your ticket shop is offline."
msgid "Automated emails are not sent as long as your ticket shop is offline."
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:44
@@ -28176,7 +28176,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:6
#, fuzzy
#| msgid "Attendee e-mail address"
msgid "Scheduled email rules"
msgid "Automated email rules"
msgstr "Correu electrònic de l'assistent"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:8
+3 -3
View File
@@ -27060,7 +27060,7 @@ msgstr[1] ""
msgstr[2] ""
#: pretix/plugins/sendmail/signals.py:99
msgid "Scheduled emails"
msgid "Automated emails"
msgstr ""
#: pretix/plugins/sendmail/signals.py:122
@@ -27138,7 +27138,7 @@ msgstr "Vytvořit e-mailové pravidlo"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:14
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:15
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:10
msgid "Scheduled emails are not sent as long as your ticket shop is offline."
msgid "Automated emails are not sent as long as your ticket shop is offline."
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:44
@@ -27185,7 +27185,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:4
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:6
msgid "Scheduled email rules"
msgid "Automated email rules"
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:8
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -27171,7 +27171,7 @@ msgstr[1] ""
#: pretix/plugins/sendmail/signals.py:99
#, fuzzy
msgid "Scheduled emails"
msgid "Automated emails"
msgstr "E-mailadresse"
#: pretix/plugins/sendmail/signals.py:122
@@ -27258,7 +27258,7 @@ msgstr "Opret en ny bruger"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:14
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:15
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:10
msgid "Scheduled emails are not sent as long as your ticket shop is offline."
msgid "Automated emails are not sent as long as your ticket shop is offline."
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:44
@@ -27311,7 +27311,7 @@ msgstr "intet valgt"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:4
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:6
#, fuzzy
msgid "Scheduled email rules"
msgid "Automated email rules"
msgstr "E-mailadresse"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:8
+6 -6
View File
@@ -28103,8 +28103,8 @@ msgstr[0] "%(count)d Tag vor Veranstaltungsbeginn um %(time)s"
msgstr[1] "%(count)d Tage vor Veranstaltungsbeginn um %(time)s"
#: pretix/plugins/sendmail/signals.py:99
msgid "Scheduled emails"
msgstr "Geplante E-Mails"
msgid "Automated emails"
msgstr "Automatisierte E-Mails"
#: pretix/plugins/sendmail/signals.py:122
msgid "Mass email was sent to customers or attendees."
@@ -28183,9 +28183,9 @@ msgstr "Neue Regel erstellen"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:14
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:15
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:10
msgid "Scheduled emails are not sent as long as your ticket shop is offline."
msgid "Automated emails are not sent as long as your ticket shop is offline."
msgstr ""
"Geplante E-Mails werden nicht verschickt, solange Ihr Ticketshop offline "
"Automatische E-Mails werden nicht verschickt, solange Ihr Ticketshop offline "
"ist."
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:44
@@ -28236,8 +28236,8 @@ msgstr "Letzte Berechnung"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:4
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:6
msgid "Scheduled email rules"
msgstr "Regeln für geplante E-Mails"
msgid "Automated email rules"
msgstr "Regeln für automatisierte E-Mails"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:8
msgid ""
@@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: 1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-07-27 11:49+0000\n"
"PO-Revision-Date: 2023-08-16 22:00+0000\n"
"Last-Translator: Felix Hartnagel <felix@fhcom.de>\n"
"PO-Revision-Date: 2023-07-28 09:11+0000\n"
"Last-Translator: Raphael Michel <michel@rami.io>\n"
"Language-Team: German (informal) <https://translate.pretix.eu/projects/"
"pretix/pretix/de_Informal/>\n"
"Language: de_Informal\n"
@@ -28055,8 +28055,8 @@ msgstr[0] "%(count)d Tag vor Veranstaltungsbeginn um %(time)s"
msgstr[1] "%(count)d Tage vor Veranstaltungsbeginn um %(time)s"
#: pretix/plugins/sendmail/signals.py:99
msgid "Scheduled emails"
msgstr "Geplante E-Mails"
msgid "Automated emails"
msgstr "Automatisierte E-Mails"
#: pretix/plugins/sendmail/signals.py:122
msgid "Mass email was sent to customers or attendees."
@@ -28135,9 +28135,9 @@ msgstr "Neue Regel erstellen"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:14
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:15
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:10
msgid "Scheduled emails are not sent as long as your ticket shop is offline."
msgid "Automated emails are not sent as long as your ticket shop is offline."
msgstr ""
"Geplante E-Mails werden nicht verschickt, solange Ihr Ticketshop offline "
"Automatische E-Mails werden nicht verschickt, solange Ihr Ticketshop offline "
"ist."
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:44
@@ -28188,8 +28188,8 @@ msgstr "Letzte Berechnung"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:4
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:6
msgid "Scheduled email rules"
msgstr "Regeln für geplante E-Mails"
msgid "Automated email rules"
msgstr "Regeln für automatisierte E-Mails"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:8
msgid ""
@@ -31019,7 +31019,7 @@ msgstr ""
#: pretix/presale/templates/pretixpresale/event/order.html:43
msgid "Please note that we still await your payment to complete the process."
msgstr ""
"Bitte beachte, dass wir noch deine Zahlung erwarten, um den Prozess "
"Bitte beachten Sie, dass wir noch deine Zahlung erwarten, um den Prozess "
"abzuschließen."
#: pretix/presale/templates/pretixpresale/event/order.html:55
+3 -3
View File
@@ -24800,7 +24800,7 @@ msgstr[0] ""
msgstr[1] ""
#: pretix/plugins/sendmail/signals.py:99
msgid "Scheduled emails"
msgid "Automated emails"
msgstr ""
#: pretix/plugins/sendmail/signals.py:122
@@ -24878,7 +24878,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:14
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:15
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:10
msgid "Scheduled emails are not sent as long as your ticket shop is offline."
msgid "Automated emails are not sent as long as your ticket shop is offline."
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:44
@@ -24925,7 +24925,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:4
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:6
msgid "Scheduled email rules"
msgid "Automated email rules"
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:8
+3 -3
View File
@@ -29895,7 +29895,7 @@ msgstr[1] ""
#: pretix/plugins/sendmail/signals.py:99
#, fuzzy
#| msgid "Attendee email"
msgid "Scheduled emails"
msgid "Automated emails"
msgstr "Email συμμετεχόντος"
#: pretix/plugins/sendmail/signals.py:122
@@ -29994,7 +29994,7 @@ msgstr "Δημιουργία νέου χρήστη"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:14
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:15
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:10
msgid "Scheduled emails are not sent as long as your ticket shop is offline."
msgid "Automated emails are not sent as long as your ticket shop is offline."
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:44
@@ -30060,7 +30060,7 @@ msgstr "Επιλογή δεδομένων"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:6
#, fuzzy
#| msgid "Attendee email"
msgid "Scheduled email rules"
msgid "Automated email rules"
msgstr "Email συμμετεχόντος"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:8
+3 -3
View File
@@ -24799,7 +24799,7 @@ msgstr[0] ""
msgstr[1] ""
#: pretix/plugins/sendmail/signals.py:99
msgid "Scheduled emails"
msgid "Automated emails"
msgstr ""
#: pretix/plugins/sendmail/signals.py:122
@@ -24877,7 +24877,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:14
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:15
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:10
msgid "Scheduled emails are not sent as long as your ticket shop is offline."
msgid "Automated emails are not sent as long as your ticket shop is offline."
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:44
@@ -24924,7 +24924,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:4
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:6
msgid "Scheduled email rules"
msgid "Automated email rules"
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:8
+3 -3
View File
@@ -29453,7 +29453,7 @@ msgstr[1] ""
#: pretix/plugins/sendmail/signals.py:99
#, fuzzy
#| msgid "Attendee email"
msgid "Scheduled emails"
msgid "Automated emails"
msgstr "Correo electrónico del participante"
#: pretix/plugins/sendmail/signals.py:122
@@ -29556,7 +29556,7 @@ msgstr "Crear un nuevo usuario"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:14
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:15
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:10
msgid "Scheduled emails are not sent as long as your ticket shop is offline."
msgid "Automated emails are not sent as long as your ticket shop is offline."
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:44
@@ -29617,7 +29617,7 @@ msgstr "Selección de datos"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:6
#, fuzzy
#| msgid "Attendee email"
msgid "Scheduled email rules"
msgid "Automated email rules"
msgstr "Correo electrónico del participante"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:8
+3 -3
View File
@@ -25621,7 +25621,7 @@ msgstr[0] ""
msgstr[1] ""
#: pretix/plugins/sendmail/signals.py:99
msgid "Scheduled emails"
msgid "Automated emails"
msgstr ""
#: pretix/plugins/sendmail/signals.py:122
@@ -25700,7 +25700,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:14
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:15
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:10
msgid "Scheduled emails are not sent as long as your ticket shop is offline."
msgid "Automated emails are not sent as long as your ticket shop is offline."
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:44
@@ -25747,7 +25747,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:4
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:6
msgid "Scheduled email rules"
msgid "Automated email rules"
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:8
+15 -9
View File
@@ -4,8 +4,8 @@ msgstr ""
"Project-Id-Version: 1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-07-27 11:49+0000\n"
"PO-Revision-Date: 2023-08-16 22:00+0000\n"
"Last-Translator: Maurice Kaag <maurice@kaag.me>\n"
"PO-Revision-Date: 2023-08-09 03:00+0000\n"
"Last-Translator: Ronan LE MEILLAT <ronan.le_meillat@highcanfly.club>\n"
"Language-Team: French <https://translate.pretix.eu/projects/pretix/pretix/fr/"
">\n"
"Language: fr\n"
@@ -247,7 +247,9 @@ msgstr ""
#: pretix/api/serializers/item.py:185 pretix/control/forms/item.py:1084
msgid "The bundled item must not have bundles on its own."
msgstr "Un produit groupé ne doit pas contenir des produits groupés."
msgstr ""
"Un forfait ne doit pas contenir des produits, qui sont eux-mêmes des "
"forfaits."
#: pretix/api/serializers/item.py:262
msgid ""
@@ -3095,7 +3097,7 @@ msgstr "Annulation"
#: pretix/base/invoice.py:620 pretix/base/invoice.py:628
msgctxt "invoice"
msgid "Description"
msgstr "Description"
msgstr "Déscription"
#: pretix/base/invoice.py:621 pretix/base/invoice.py:629
msgctxt "invoice"
@@ -6803,12 +6805,16 @@ msgid "List of Add-Ons"
msgstr "Liste des Addons"
#: pretix/base/pdf.py:364
#, fuzzy
#| msgid ""
#| "Add-on 1\n"
#| "Add-on 2"
msgid ""
"Add-on 1\n"
"2x Add-on 2"
msgstr ""
"Add-on 1\n"
"2x Add-on 2"
"Add-on 2"
#: pretix/base/pdf.py:370 pretix/control/forms/filter.py:1275
#: pretix/control/forms/filter.py:1277
@@ -11130,7 +11136,7 @@ msgstr "Degré (après le nom)"
#: pretix/base/settings.py:3577
msgctxt "person_name_sample"
msgid "MA"
msgstr "MA"
msgstr ""
#: pretix/base/settings.py:3684 pretix/control/forms/event.py:217
msgid ""
@@ -28317,7 +28323,7 @@ msgstr[0] "%(count)d jour avant le début de l'événement à %(time)s"
msgstr[1] "%(count)d jours avant le début de l'événement à %(time)s"
#: pretix/plugins/sendmail/signals.py:99
msgid "Scheduled emails"
msgid "Automated emails"
msgstr "E-mails automatisés"
#: pretix/plugins/sendmail/signals.py:122
@@ -28398,7 +28404,7 @@ msgstr "Créer une règle de-mail"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:14
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:15
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:10
msgid "Scheduled emails are not sent as long as your ticket shop is offline."
msgid "Automated emails are not sent as long as your ticket shop is offline."
msgstr ""
"Les e-mails automatisés ne sont pas envoyés tant que votre billetterie est "
"hors ligne."
@@ -28451,7 +28457,7 @@ msgstr "Calcul du dernier planning"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:4
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:6
msgid "Scheduled email rules"
msgid "Automated email rules"
msgstr "Règles de-mails automatiques"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:8
+3 -3
View File
@@ -30019,7 +30019,7 @@ msgstr[1] ""
#: pretix/plugins/sendmail/signals.py:99
#, fuzzy
msgid "Scheduled emails"
msgid "Automated emails"
msgstr "Correo electrónico del participante"
#: pretix/plugins/sendmail/signals.py:122
@@ -30113,7 +30113,7 @@ msgstr "Crear un nuevo usuario"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:14
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:15
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:10
msgid "Scheduled emails are not sent as long as your ticket shop is offline."
msgid "Automated emails are not sent as long as your ticket shop is offline."
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:44
@@ -30168,7 +30168,7 @@ msgstr "Selección de datos"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:4
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:6
#, fuzzy
msgid "Scheduled email rules"
msgid "Automated email rules"
msgstr "Correo electrónico del participante"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:8
+3 -3
View File
@@ -24825,7 +24825,7 @@ msgstr[0] ""
msgstr[1] ""
#: pretix/plugins/sendmail/signals.py:99
msgid "Scheduled emails"
msgid "Automated emails"
msgstr ""
#: pretix/plugins/sendmail/signals.py:122
@@ -24903,7 +24903,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:14
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:15
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:10
msgid "Scheduled emails are not sent as long as your ticket shop is offline."
msgid "Automated emails are not sent as long as your ticket shop is offline."
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:44
@@ -24950,7 +24950,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:4
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:6
msgid "Scheduled email rules"
msgid "Automated email rules"
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:8
+3 -3
View File
@@ -24809,7 +24809,7 @@ msgstr[0] ""
msgstr[1] ""
#: pretix/plugins/sendmail/signals.py:99
msgid "Scheduled emails"
msgid "Automated emails"
msgstr ""
#: pretix/plugins/sendmail/signals.py:122
@@ -24887,7 +24887,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:14
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:15
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:10
msgid "Scheduled emails are not sent as long as your ticket shop is offline."
msgid "Automated emails are not sent as long as your ticket shop is offline."
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:44
@@ -24934,7 +24934,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:4
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:6
msgid "Scheduled email rules"
msgid "Automated email rules"
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:8
+3 -3
View File
@@ -25417,7 +25417,7 @@ msgstr[0] ""
msgstr[1] ""
#: pretix/plugins/sendmail/signals.py:99
msgid "Scheduled emails"
msgid "Automated emails"
msgstr ""
#: pretix/plugins/sendmail/signals.py:122
@@ -25503,7 +25503,7 @@ msgstr "Kifizetett megrendelések"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:14
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:15
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:10
msgid "Scheduled emails are not sent as long as your ticket shop is offline."
msgid "Automated emails are not sent as long as your ticket shop is offline."
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:44
@@ -25552,7 +25552,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:4
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:6
msgid "Scheduled email rules"
msgid "Automated email rules"
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:8
+3 -3
View File
@@ -24799,7 +24799,7 @@ msgstr[0] ""
msgstr[1] ""
#: pretix/plugins/sendmail/signals.py:99
msgid "Scheduled emails"
msgid "Automated emails"
msgstr ""
#: pretix/plugins/sendmail/signals.py:122
@@ -24877,7 +24877,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:14
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:15
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:10
msgid "Scheduled emails are not sent as long as your ticket shop is offline."
msgid "Automated emails are not sent as long as your ticket shop is offline."
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:44
@@ -24924,7 +24924,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:4
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:6
msgid "Scheduled email rules"
msgid "Automated email rules"
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:8
+3 -3
View File
@@ -25888,7 +25888,7 @@ msgstr[1] ""
#: pretix/plugins/sendmail/signals.py:99
#, fuzzy
msgid "Scheduled emails"
msgid "Automated emails"
msgstr "Email partecipante"
#: pretix/plugins/sendmail/signals.py:122
@@ -25978,7 +25978,7 @@ msgstr "Data di creazione"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:14
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:15
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:10
msgid "Scheduled emails are not sent as long as your ticket shop is offline."
msgid "Automated emails are not sent as long as your ticket shop is offline."
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:44
@@ -26028,7 +26028,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:4
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:6
#, fuzzy
msgid "Scheduled email rules"
msgid "Automated email rules"
msgstr "Email partecipante"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:8
+3 -3
View File
@@ -25094,7 +25094,7 @@ msgid_plural "%(count)d days before event start at %(time)s"
msgstr[0] ""
#: pretix/plugins/sendmail/signals.py:99
msgid "Scheduled emails"
msgid "Automated emails"
msgstr ""
#: pretix/plugins/sendmail/signals.py:122
@@ -25172,7 +25172,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:14
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:15
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:10
msgid "Scheduled emails are not sent as long as your ticket shop is offline."
msgid "Automated emails are not sent as long as your ticket shop is offline."
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:44
@@ -25219,7 +25219,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:4
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:6
msgid "Scheduled email rules"
msgid "Automated email rules"
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:8
+3 -3
View File
@@ -24800,7 +24800,7 @@ msgstr[0] ""
msgstr[1] ""
#: pretix/plugins/sendmail/signals.py:99
msgid "Scheduled emails"
msgid "Automated emails"
msgstr ""
#: pretix/plugins/sendmail/signals.py:122
@@ -24878,7 +24878,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:14
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:15
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:10
msgid "Scheduled emails are not sent as long as your ticket shop is offline."
msgid "Automated emails are not sent as long as your ticket shop is offline."
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:44
@@ -24925,7 +24925,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:4
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:6
msgid "Scheduled email rules"
msgid "Automated email rules"
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:8
+3 -3
View File
@@ -24801,7 +24801,7 @@ msgstr[0] ""
msgstr[1] ""
#: pretix/plugins/sendmail/signals.py:99
msgid "Scheduled emails"
msgid "Automated emails"
msgstr ""
#: pretix/plugins/sendmail/signals.py:122
@@ -24879,7 +24879,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:14
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:15
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:10
msgid "Scheduled emails are not sent as long as your ticket shop is offline."
msgid "Automated emails are not sent as long as your ticket shop is offline."
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:44
@@ -24926,7 +24926,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:4
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:6
msgid "Scheduled email rules"
msgid "Automated email rules"
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:8
+3 -3
View File
@@ -26285,7 +26285,7 @@ msgstr[2] ""
#: pretix/plugins/sendmail/signals.py:99
#, fuzzy
#| msgid "Attendee email"
msgid "Scheduled emails"
msgid "Automated emails"
msgstr "Apmeklētāja e-pasts"
#: pretix/plugins/sendmail/signals.py:122
@@ -26365,7 +26365,7 @@ msgstr "Datums un laiks"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:14
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:15
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:10
msgid "Scheduled emails are not sent as long as your ticket shop is offline."
msgid "Automated emails are not sent as long as your ticket shop is offline."
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:44
@@ -26422,7 +26422,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:6
#, fuzzy
#| msgid "Attendee email"
msgid "Scheduled email rules"
msgid "Automated email rules"
msgstr "Apmeklētāja e-pasts"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:8
+3 -3
View File
@@ -24799,7 +24799,7 @@ msgstr[0] ""
msgstr[1] ""
#: pretix/plugins/sendmail/signals.py:99
msgid "Scheduled emails"
msgid "Automated emails"
msgstr ""
#: pretix/plugins/sendmail/signals.py:122
@@ -24877,7 +24877,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:14
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:15
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:10
msgid "Scheduled emails are not sent as long as your ticket shop is offline."
msgid "Automated emails are not sent as long as your ticket shop is offline."
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:44
@@ -24924,7 +24924,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:4
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:6
msgid "Scheduled email rules"
msgid "Automated email rules"
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:8
@@ -25337,7 +25337,7 @@ msgstr[0] ""
msgstr[1] ""
#: pretix/plugins/sendmail/signals.py:99
msgid "Scheduled emails"
msgid "Automated emails"
msgstr ""
#: pretix/plugins/sendmail/signals.py:122
@@ -25419,7 +25419,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:14
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:15
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:10
msgid "Scheduled emails are not sent as long as your ticket shop is offline."
msgid "Automated emails are not sent as long as your ticket shop is offline."
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:44
@@ -25466,7 +25466,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:4
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:6
msgid "Scheduled email rules"
msgid "Automated email rules"
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:8
+124 -60
View File
@@ -7,16 +7,16 @@ msgstr ""
"Project-Id-Version: 1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-07-27 11:49+0000\n"
"PO-Revision-Date: 2023-08-25 04:00+0000\n"
"Last-Translator: Alain <alain@waag.org>\n"
"Language-Team: Dutch <https://translate.pretix.eu/projects/pretix/pretix/nl/>"
"\n"
"PO-Revision-Date: 2023-07-16 22:00+0000\n"
"Last-Translator: Freek Engelbarts <freekengelbarts@gmail.com>\n"
"Language-Team: Dutch <https://translate.pretix.eu/projects/pretix/pretix/nl/"
">\n"
"Language: nl\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 4.18.2\n"
"X-Generator: Weblate 4.17\n"
#: pretix/_base_settings.py:78
msgid "English"
@@ -411,7 +411,7 @@ msgstr "Bestelling is verlopen"
#: pretix/api/webhooks.py:234
msgid "Order expiry date changed"
msgstr "Verloopdatum aangepast"
msgstr "Verloopdatum aangepast."
#: pretix/api/webhooks.py:238 pretix/base/notifications.py:269
msgid "Order information changed"
@@ -534,8 +534,10 @@ msgid "Waiting list entry deleted"
msgstr "Wachtlijstitem verwijderd"
#: pretix/api/webhooks.py:351
#, fuzzy
#| msgid "Waiting list entries"
msgid "Waiting list entry received voucher"
msgstr "Wachtlijstitem heeft voucher ontvangen"
msgstr "Wachtlijstitems"
#: pretix/base/addressvalidation.py:100 pretix/base/addressvalidation.py:103
#: pretix/base/addressvalidation.py:108 pretix/base/forms/questions.py:938
@@ -551,11 +553,11 @@ msgstr "Dit veld is verplicht."
#: pretix/base/addressvalidation.py:213
msgid "Enter a postal code in the format XXX."
msgstr "Postcode in het formaat XXX invoeren."
msgstr "Voer een postcode in in het formaat XXX."
#: pretix/base/addressvalidation.py:222 pretix/base/addressvalidation.py:224
msgid "Enter a postal code in the format XXXX."
msgstr "Postcode in het format XXXX invoeren."
msgstr "Voer een postcode in in het format XXXX."
#: pretix/base/auth.py:143
#, python-brace-format
@@ -2309,7 +2311,7 @@ msgstr ""
#: pretix/base/exporters/orderlist.py:887
msgid "Converted from legacy version"
msgstr "Vanuit oudere versie geconverteerd"
msgstr ""
#: pretix/base/exporters/orderlist.py:949
msgid "Payments and refunds"
@@ -4378,7 +4380,7 @@ msgstr ""
#: pretix/base/models/items.py:662
msgid "Reusable media type"
msgstr "Mediatype"
msgstr ""
#: pretix/base/models/items.py:664
msgid ""
@@ -6144,7 +6146,7 @@ msgstr "Vul een geldige taalcode in."
#: pretix/base/orderimport.py:669 pretix/base/orderimport.py:692
#, python-brace-format
msgid "Could not parse {value} as a date and time."
msgstr "Kon {value} niet als datum en tijd herkennen."
msgstr ""
#: pretix/base/orderimport.py:711
msgid "Please enter a valid sales channel."
@@ -6845,7 +6847,7 @@ msgstr "Geldig tot"
#: pretix/base/pdf.py:457
msgid "Reusable Medium ID"
msgstr "Media-ID"
msgstr ""
#: pretix/base/pdf.py:462
msgid "Seat: Full name"
@@ -7045,30 +7047,38 @@ msgstr ""
"door u gekozen hoeveelheid. Zie hieronder voor de details."
#: pretix/base/services/cart.py:114
#, python-format
#, fuzzy, python-format
#| msgid "You cannot select more than %s items per order."
msgid "You cannot select more than %s item per order."
msgid_plural "You cannot select more than %s items per order."
msgstr[0] "U kunt niet meer dan %s item per bestelling kiezen."
msgstr[0] "U kunt niet meer dan %s items per bestelling kiezen."
msgstr[1] "U kunt niet meer dan %s items per bestelling kiezen."
#: pretix/base/services/cart.py:118 pretix/base/services/orders.py:1468
#, python-format
#, fuzzy, python-format
#| msgid ""
#| "You cannot select more than %(max)s items of the product %(product)s."
msgid "You cannot select more than %(max)s item of the product %(product)s."
msgid_plural ""
"You cannot select more than %(max)s items of the product %(product)s."
msgstr[0] "U kunt niet meer dan %(max)s item van product %(product)s kiezen."
msgstr[0] "U kunt niet meer dan %(max)s items van product %(product)s kiezen."
msgstr[1] "U kunt niet meer dan %(max)s items van product %(product)s kiezen."
#: pretix/base/services/cart.py:123 pretix/base/services/orders.py:1473
#, python-format
#, fuzzy, python-format
#| msgid ""
#| "You need to select at least %(min)s items of the product %(product)s."
msgid "You need to select at least %(min)s item of the product %(product)s."
msgid_plural ""
"You need to select at least %(min)s items of the product %(product)s."
msgstr[0] "U moet ten minste %(min)s item van product %(product)s kiezen."
msgstr[0] "U moet ten minste %(min)s items van product %(product)s kiezen."
msgstr[1] "U moet ten minste %(min)s items van product %(product)s kiezen."
#: pretix/base/services/cart.py:128
#, python-format
#, fuzzy, python-format
#| msgid ""
#| "We removed %(product)s from your cart as you can not buy less than "
#| "%(min)s items of it."
msgid ""
"We removed %(product)s from your cart as you can not buy less than %(min)s "
"item of it."
@@ -7077,10 +7087,10 @@ msgid_plural ""
"items of it."
msgstr[0] ""
"We hebben %(product)s uit uw winkelwagen verwijderd, omdat u niet minder dan "
"%(min)s item ervan kunt kopen."
"%(min)s ervan kunt kopen."
msgstr[1] ""
"We hebben %(product)s uit uw winkelwagen verwijderd, omdat u niet minder dan "
"%(min)s items ervan kunt kopen."
"%(min)s ervan kunt kopen."
#: pretix/base/services/cart.py:132 pretix/base/services/orders.py:146
#: pretix/presale/templates/pretixpresale/event/index.html:157
@@ -7242,7 +7252,10 @@ msgid "You can not select two variations of the same add-on product."
msgstr "U kunt niet twee varianten van hetzelfde add-on-product selecteren."
#: pretix/base/services/cart.py:185 pretix/base/services/orders.py:184
#, python-format
#, fuzzy, python-format
#| msgid ""
#| "You can select at most %(max)s add-ons from the category %(cat)s for the "
#| "product %(base)s."
msgid ""
"You can select at most %(max)s add-on from the category %(cat)s for the "
"product %(base)s."
@@ -7250,14 +7263,17 @@ msgid_plural ""
"You can select at most %(max)s add-ons from the category %(cat)s for the "
"product %(base)s."
msgstr[0] ""
"U kunt maximaal %(max)s add-on van de categorie %(cat)s selecteren voor het "
"U kunt maximaal %(max)s add-ons van de categorie %(cat)s selecteren voor het "
"product %(base)s."
msgstr[1] ""
"U kunt maximaal %(max)s add-ons van de categorie %(cat)s selecteren voor het "
"product %(base)s."
#: pretix/base/services/cart.py:190 pretix/base/services/orders.py:189
#, python-format
#, fuzzy, python-format
#| msgid ""
#| "You need to select at least %(min)s add-ons from the category %(cat)s for "
#| "the product %(base)s."
msgid ""
"You need to select at least %(min)s add-on from the category %(cat)s for the "
"product %(base)s."
@@ -7265,7 +7281,7 @@ msgid_plural ""
"You need to select at least %(min)s add-ons from the category %(cat)s for "
"the product %(base)s."
msgstr[0] ""
"U moet minimaal %(min)s add-on van de categorie %(cat)s selecteren voor het "
"U moet minimaal %(min)s add-ons van de categorie %(cat)s selecteren voor het "
"product %(base)s."
msgstr[1] ""
"U moet minimaal %(min)s add-ons van de categorie %(cat)s selecteren voor het "
@@ -7430,14 +7446,16 @@ msgid "This ticket has been blocked."
msgstr "Dit ticket werd reeds eenmaal gebruikt."
#: pretix/base/services/checkin.py:781 pretix/base/services/checkin.py:785
#, python-brace-format
#, fuzzy, python-brace-format
#| msgid "Only allowed after {datetime}"
msgid "This ticket is only valid after {datetime}."
msgstr "Dit ticket is geldig vanaf {datetime}."
msgstr "Alleen toegestaan vanaf {datetime}"
#: pretix/base/services/checkin.py:795 pretix/base/services/checkin.py:799
#, python-brace-format
#, fuzzy, python-brace-format
#| msgid "This ticket has already been redeemed."
msgid "This ticket was only valid before {datetime}."
msgstr "Dit ticket was geldig vòòr {datetime}."
msgstr "Dit ticket is al gebruikt."
#: pretix/base/services/checkin.py:830
msgid "This order position has an invalid product for this check-in list."
@@ -7498,14 +7516,14 @@ msgid "Export failed"
msgstr "Geëxporteerde bestanden"
#: pretix/base/services/export.py:206
#, fuzzy
#| msgid "Permission denied"
msgid "Permission denied."
msgstr "Geen toestemming."
msgstr "Geen toestemming"
#: pretix/base/services/export.py:221
msgid "Your exported data exceeded the size limit for scheduled exports."
msgstr ""
"De door u geëxporteerde data overschrijdt de grootte-limiet voor geplande "
"exports."
#: pretix/base/services/invoices.py:103
#, python-brace-format
@@ -7530,10 +7548,11 @@ msgstr ""
"{country}"
#: pretix/base/services/invoices.py:220 pretix/base/services/invoices.py:257
#, python-brace-format
#, fuzzy, python-brace-format
#| msgid "Event location"
msgctxt "invoice"
msgid "Event location: {location}"
msgstr "Evenementlocatie: {location}"
msgstr "Evenementlocatie"
#: pretix/base/services/invoices.py:236
#, python-brace-format
@@ -7747,7 +7766,10 @@ msgid "Your cart is empty."
msgstr "Uw winkelwagen is leeg."
#: pretix/base/services/orders.py:138
#, python-format
#, fuzzy, python-format
#| msgid ""
#| "You cannot select more than %(max)s items of the product %(product)s. We "
#| "removed the surplus items from your cart."
msgid ""
"You cannot select more than %(max)s item of the product %(product)s. We "
"removed the surplus items from your cart."
@@ -7755,11 +7777,11 @@ msgid_plural ""
"You cannot select more than %(max)s items of the product %(product)s. We "
"removed the surplus items from your cart."
msgstr[0] ""
"U kunt van het product %(product)s niet meer dan %(max)s per bestelling "
"kiezen. We hebben de overtallige producten uit uw winkelwagen verwijderd."
"U kunt niet meer dan %(max)s kopieën van het product %(product)s kiezen. We "
"hebben het overschot uit uw winkelwagen verwijderd."
msgstr[1] ""
"U kunt van het product %(product)s niet meer dan %(max)s per bestelling "
"kiezen. We hebben de overtallige producten uit uw winkelwagen verwijderd."
"U kunt niet meer dan %(max)s kopieën van het product %(product)s kiezen. We "
"hebben het overschot uit uw winkelwagen verwijderd."
#: pretix/base/services/orders.py:147
msgid "The booking period has ended."
@@ -7809,9 +7831,10 @@ msgstr ""
"niet geldig voor dit item. We hebben dit item uit uw winkelwagen verwijderd."
#: pretix/base/services/orders.py:168
#, fuzzy
#| msgid "You need a valid voucher code to order this product."
msgid "You need a valid voucher code to order one of the products."
msgstr ""
"U heeft een geldige vouchercode nodig om een van de producten te bestellen."
msgstr "U heeft een geldige vouchercode nodig om dit product te bestellen."
#: pretix/base/services/orders.py:170
msgid ""
@@ -7850,8 +7873,10 @@ msgstr ""
"is besteld."
#: pretix/base/services/orders.py:210
#, fuzzy
#| msgid "The order has been canceled."
msgid "The order was not canceled."
msgstr "De bestelling is niet geannuleerd."
msgstr "De bestelling is geannuleerd."
#: pretix/base/services/orders.py:265 pretix/control/forms/orders.py:120
msgid "The new expiry date needs to be in the future."
@@ -7887,8 +7912,10 @@ msgstr ""
"bestelling is betaald."
#: pretix/base/services/orders.py:918
#, fuzzy
#| msgid "This payment method does not support automatic refunds."
msgid "The selected payment methods do not cover the total balance."
msgstr "Deze betalingsmethode dekt het volledige bedrag niet."
msgstr "Deze betalingsmethode ondersteunt geen automatische terugbetalingen."
#: pretix/base/services/orders.py:990
msgid ""
@@ -8043,8 +8070,10 @@ msgid "Something happened in your event after the export, please try again."
msgstr "Er is iets gebeurd in uw evenement na de export, probeer het opnieuw."
#: pretix/base/services/shredder.py:177
#, fuzzy
#| msgid "Payment completed."
msgid "Data shredding completed"
msgstr "Verwijderen van data voltooid."
msgstr "Betaling voltooid."
#: pretix/base/services/stats.py:210
msgid "Uncategorized"
@@ -10071,7 +10100,19 @@ msgid "Your order is pending payment: {code}"
msgstr "Uw bestelling wacht op betaling: {code}"
#: pretix/base/settings.py:2316
#, python-brace-format
#, fuzzy, python-brace-format
#| msgid ""
#| "Hello,\n"
#| "\n"
#| "we did not yet receive a full payment for your order for {event}.\n"
#| "Please keep in mind that we only guarantee your order if we receive\n"
#| "your payment before {expire_date}.\n"
#| "\n"
#| "You can view the payment information and the status of your order at\n"
#| "{url}\n"
#| "\n"
#| "Best regards, \n"
#| "Your {event} team"
msgid ""
"Hello,\n"
"\n"
@@ -10094,7 +10135,7 @@ msgstr ""
"U kunt de betalingsinformatie en de status van uw bestelling inzien op\n"
"{url}.\n"
"\n"
"Met vriendelijke groet, \n"
"Met vriendelijke groet,\n"
"De organisatoren van {event}"
#: pretix/base/settings.py:2329
@@ -10104,7 +10145,19 @@ msgid "Incomplete payment received: {code}"
msgstr "Betaling ontvangen voor uw bestelling: {code}"
#: pretix/base/settings.py:2333
#, python-brace-format
#, fuzzy, python-brace-format
#| msgid ""
#| "Hello,\n"
#| "\n"
#| "we did not yet receive a full payment for your order for {event}.\n"
#| "Please keep in mind that we only guarantee your order if we receive\n"
#| "your payment before {expire_date}.\n"
#| "\n"
#| "You can view the payment information and the status of your order at\n"
#| "{url}\n"
#| "\n"
#| "Best regards, \n"
#| "Your {event} team"
msgid ""
"Hello,\n"
"\n"
@@ -10122,11 +10175,10 @@ msgid ""
msgstr ""
"Hallo,\n"
"\n"
"We hebben een betaling ontvangen voor {event}\n"
"\n"
"Helaas is het ontvangen bedrag minder dan het volledige verschuldigde "
"bedrag. Graag nog het bedrag van **{pending_sum}** voldoen om de bestelling "
"te voltooien.\n"
"We hebben nog geen volledige betaling ontvangen voor uw bestelling voor "
"{event}.\n"
"We kunnen uw bestelling alleen garanderen als we uw betaling ontvangen\n"
"voor {expire_date}.\n"
"\n"
"U kunt de betalingsinformatie en de status van uw bestelling inzien op\n"
"{url}.\n"
@@ -10315,7 +10367,17 @@ msgstr ""
"Organisatie van {event}"
#: pretix/base/settings.py:2446 pretix/base/settings.py:2483
#, python-brace-format
#, fuzzy, python-brace-format
#| msgid ""
#| "Hello {attendee_name},\n"
#| "\n"
#| "a ticket for {event} has been ordered for you.\n"
#| "\n"
#| "You can view the details and status of your ticket here:\n"
#| "{url}\n"
#| "\n"
#| "Best regards, \n"
#| "Your {event} team"
msgid ""
"Hello,\n"
"\n"
@@ -10327,9 +10389,9 @@ msgid ""
"Best regards, \n"
"Your {event} team"
msgstr ""
"Beste,\n"
"Beste {attendee_name},\n"
"\n"
"Uw ticket voor {event} is geaccordeerd.\n"
"Er is een ticket voor {event} voor u besteld.\n"
"\n"
"U kunt de details en status van uw ticket hier bekijken:\n"
"{url}\n"
@@ -17233,8 +17295,10 @@ msgid "Valid check-in"
msgstr "Alle check-ins"
#: pretix/control/templates/pretixcontrol/checkin/simulator.html:67
#, fuzzy
#| msgid "Additional information"
msgid "Additional information required"
msgstr "Extra informatie vereist"
msgstr "Extra informatie"
#: pretix/control/templates/pretixcontrol/checkin/simulator.html:69
msgid ""
@@ -28479,7 +28543,7 @@ msgstr[0] "%(count)d dag voor de start van het evenement om %(time)s"
msgstr[1] "%(count)d dagen voor de start van het evenement om %(time)s"
#: pretix/plugins/sendmail/signals.py:99
msgid "Scheduled emails"
msgid "Automated emails"
msgstr "Automatische e-mails"
#: pretix/plugins/sendmail/signals.py:122
@@ -28567,7 +28631,7 @@ msgstr "Maak e-mailregel"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:14
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:15
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:10
msgid "Scheduled emails are not sent as long as your ticket shop is offline."
msgid "Automated emails are not sent as long as your ticket shop is offline."
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:44
@@ -28622,7 +28686,7 @@ msgstr "Laatst uitgevoerd"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:4
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:6
msgid "Scheduled email rules"
msgid "Automated email rules"
msgstr "Automatische e-mailregels"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:8
+4 -4
View File
@@ -7,8 +7,8 @@ msgstr ""
"Project-Id-Version: 1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-07-21 11:46+0000\n"
"PO-Revision-Date: 2023-08-24 04:00+0000\n"
"Last-Translator: Alain <alain@waag.org>\n"
"PO-Revision-Date: 2021-10-29 02:00+0000\n"
"Last-Translator: Maarten van den Berg <maartenberg1@gmail.com>\n"
"Language-Team: Dutch <https://translate.pretix.eu/projects/pretix/pretix-js/"
"nl/>\n"
"Language: nl\n"
@@ -16,7 +16,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 4.18.2\n"
"X-Generator: Weblate 4.8\n"
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
@@ -252,7 +252,7 @@ msgstr "Dit ticket is nog niet betaald. Wilt u toch doorgaan?"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:51
msgid "Additional information required"
msgstr "Extra informatie vereist"
msgstr "Extra informatie nodig"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:52
msgid "Valid ticket"
@@ -24801,7 +24801,7 @@ msgstr[0] ""
msgstr[1] ""
#: pretix/plugins/sendmail/signals.py:99
msgid "Scheduled emails"
msgid "Automated emails"
msgstr ""
#: pretix/plugins/sendmail/signals.py:122
@@ -24879,7 +24879,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:14
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:15
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:10
msgid "Scheduled emails are not sent as long as your ticket shop is offline."
msgid "Automated emails are not sent as long as your ticket shop is offline."
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:44
@@ -24926,7 +24926,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:4
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:6
msgid "Scheduled email rules"
msgid "Automated email rules"
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:8
@@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-07-27 11:49+0000\n"
"PO-Revision-Date: 2023-08-24 04:00+0000\n"
"Last-Translator: Alain <alain@waag.org>\n"
"PO-Revision-Date: 2023-07-16 22:00+0000\n"
"Last-Translator: Freek Engelbarts <freekengelbarts@gmail.com>\n"
"Language-Team: Dutch (informal) <https://translate.pretix.eu/projects/pretix/"
"pretix/nl_Informal/>\n"
"Language: nl_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 4.18.2\n"
"X-Generator: Weblate 4.17\n"
#: pretix/_base_settings.py:78
msgid "English"
@@ -555,8 +555,10 @@ msgid "Waiting list entry deleted"
msgstr "Wachtlijstitem"
#: pretix/api/webhooks.py:351
#, fuzzy
#| msgid "Waiting list entries"
msgid "Waiting list entry received voucher"
msgstr "Wachtlijstitem heeft voucher ontvangen"
msgstr "Wachtlijstitems"
#: pretix/base/addressvalidation.py:100 pretix/base/addressvalidation.py:103
#: pretix/base/addressvalidation.py:108 pretix/base/forms/questions.py:938
@@ -28783,7 +28785,7 @@ msgstr[1] ""
#: pretix/plugins/sendmail/signals.py:99
#, fuzzy
#| msgid "Attendee email"
msgid "Scheduled emails"
msgid "Automated emails"
msgstr "E-mailadres van gast"
#: pretix/plugins/sendmail/signals.py:122
@@ -28877,7 +28879,7 @@ msgstr "Maak een nieuwe gebruiker aan"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:14
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:15
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:10
msgid "Scheduled emails are not sent as long as your ticket shop is offline."
msgid "Automated emails are not sent as long as your ticket shop is offline."
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:44
@@ -28941,7 +28943,7 @@ msgstr "Datakeuze"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:6
#, fuzzy
#| msgid "Attendee e-mail address"
msgid "Scheduled email rules"
msgid "Automated email rules"
msgstr "E-mailadres van gast"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:8
+3 -3
View File
@@ -26566,7 +26566,7 @@ msgstr[2] ""
#: pretix/plugins/sendmail/signals.py:99
#, fuzzy
#| msgid "Attendee email"
msgid "Scheduled emails"
msgid "Automated emails"
msgstr "Adres email uczestnika"
#: pretix/plugins/sendmail/signals.py:122
@@ -26660,7 +26660,7 @@ msgstr "Data stworzenia"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:14
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:15
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:10
msgid "Scheduled emails are not sent as long as your ticket shop is offline."
msgid "Automated emails are not sent as long as your ticket shop is offline."
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:44
@@ -26711,7 +26711,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:6
#, fuzzy
#| msgid "Attendee email"
msgid "Scheduled email rules"
msgid "Automated email rules"
msgstr "Adres email uczestnika"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:8
@@ -24820,7 +24820,7 @@ msgstr[1] ""
msgstr[2] ""
#: pretix/plugins/sendmail/signals.py:99
msgid "Scheduled emails"
msgid "Automated emails"
msgstr ""
#: pretix/plugins/sendmail/signals.py:122
@@ -24898,7 +24898,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:14
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:15
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:10
msgid "Scheduled emails are not sent as long as your ticket shop is offline."
msgid "Automated emails are not sent as long as your ticket shop is offline."
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:44
@@ -24945,7 +24945,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:4
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:6
msgid "Scheduled email rules"
msgid "Automated email rules"
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:8
+3 -3
View File
@@ -25093,7 +25093,7 @@ msgstr[0] ""
msgstr[1] ""
#: pretix/plugins/sendmail/signals.py:99
msgid "Scheduled emails"
msgid "Automated emails"
msgstr ""
#: pretix/plugins/sendmail/signals.py:122
@@ -25171,7 +25171,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:14
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:15
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:10
msgid "Scheduled emails are not sent as long as your ticket shop is offline."
msgid "Automated emails are not sent as long as your ticket shop is offline."
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:44
@@ -25218,7 +25218,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:4
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:6
msgid "Scheduled email rules"
msgid "Automated email rules"
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:8
@@ -27358,7 +27358,7 @@ msgstr[1] ""
#: pretix/plugins/sendmail/signals.py:99
#, fuzzy
#| msgid "Attendee email"
msgid "Scheduled emails"
msgid "Automated emails"
msgstr "E-mail do participante"
#: pretix/plugins/sendmail/signals.py:122
@@ -27452,7 +27452,7 @@ msgstr "Tipo de dispositivo"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:14
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:15
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:10
msgid "Scheduled emails are not sent as long as your ticket shop is offline."
msgid "Automated emails are not sent as long as your ticket shop is offline."
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:44
@@ -27506,7 +27506,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:6
#, fuzzy
#| msgid "Attendee email"
msgid "Scheduled email rules"
msgid "Automated email rules"
msgstr "E-mail do participante"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:8
@@ -28193,7 +28193,7 @@ msgstr[0] "%(count)d dia antes do início do evento às %(time)s"
msgstr[1] "%(count)d dias antes do início do evento às %(time)s"
#: pretix/plugins/sendmail/signals.py:99
msgid "Scheduled emails"
msgid "Automated emails"
msgstr "E -mails automatizados"
#: pretix/plugins/sendmail/signals.py:122
@@ -28275,7 +28275,7 @@ msgstr "Crie regra de email"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:14
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:15
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:10
msgid "Scheduled emails are not sent as long as your ticket shop is offline."
msgid "Automated emails are not sent as long as your ticket shop is offline."
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:44
@@ -28326,7 +28326,7 @@ msgstr "Última programação Computação"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:4
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:6
msgid "Scheduled email rules"
msgid "Automated email rules"
msgstr "Regras de email automatizadas"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:8
+3 -3
View File
@@ -28777,7 +28777,7 @@ msgstr[1] "cu %(count)d zile înainte de începerea evenimentului la %(time)s"
msgstr[2] "cu %(count)d zile înainte de începerea evenimentului la %(time)s"
#: pretix/plugins/sendmail/signals.py:99
msgid "Scheduled emails"
msgid "Automated emails"
msgstr "E-mailuri automate"
#: pretix/plugins/sendmail/signals.py:122
@@ -28861,7 +28861,7 @@ msgstr "Creați o regulă de e-mail"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:14
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:15
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:10
msgid "Scheduled emails are not sent as long as your ticket shop is offline."
msgid "Automated emails are not sent as long as your ticket shop is offline."
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:44
@@ -28914,7 +28914,7 @@ msgstr "Calculul ultimului program"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:4
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:6
msgid "Scheduled email rules"
msgid "Automated email rules"
msgstr "Reguli automatizate de e-mail"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:8
+3 -3
View File
@@ -27155,7 +27155,7 @@ msgstr[2] ""
#: pretix/plugins/sendmail/signals.py:99
#, fuzzy
#| msgid "Attendee email"
msgid "Scheduled emails"
msgid "Automated emails"
msgstr "Адрес электронной почты посетителя"
#: pretix/plugins/sendmail/signals.py:122
@@ -27241,7 +27241,7 @@ msgstr "Дата и время"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:14
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:15
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:10
msgid "Scheduled emails are not sent as long as your ticket shop is offline."
msgid "Automated emails are not sent as long as your ticket shop is offline."
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:44
@@ -27297,7 +27297,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:6
#, fuzzy
#| msgid "Attendee email"
msgid "Scheduled email rules"
msgid "Automated email rules"
msgstr "Адрес электронной почты посетителя"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:8
+3 -3
View File
@@ -24872,7 +24872,7 @@ msgstr[0] ""
msgstr[1] ""
#: pretix/plugins/sendmail/signals.py:99
msgid "Scheduled emails"
msgid "Automated emails"
msgstr ""
#: pretix/plugins/sendmail/signals.py:122
@@ -24950,7 +24950,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:14
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:15
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:10
msgid "Scheduled emails are not sent as long as your ticket shop is offline."
msgid "Automated emails are not sent as long as your ticket shop is offline."
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:44
@@ -24997,7 +24997,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:4
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:6
msgid "Scheduled email rules"
msgid "Automated email rules"
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:8
+3 -3
View File
@@ -26953,7 +26953,7 @@ msgstr[3] ""
#: pretix/plugins/sendmail/signals.py:99
#, fuzzy
#| msgid "Attendee email"
msgid "Scheduled emails"
msgid "Automated emails"
msgstr "Email udeleženca"
#: pretix/plugins/sendmail/signals.py:122
@@ -27041,7 +27041,7 @@ msgstr "Datum ustvarjenja"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:14
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:15
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:10
msgid "Scheduled emails are not sent as long as your ticket shop is offline."
msgid "Automated emails are not sent as long as your ticket shop is offline."
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:44
@@ -27094,7 +27094,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:6
#, fuzzy
#| msgid "Attendee e-mail address"
msgid "Scheduled email rules"
msgid "Automated email rules"
msgstr "E-poštni naslov udeleženca"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:8
+3 -3
View File
@@ -26970,7 +26970,7 @@ msgstr[1] ""
#: pretix/plugins/sendmail/signals.py:99
#, fuzzy
#| msgid "Attendee email"
msgid "Scheduled emails"
msgid "Automated emails"
msgstr "Epost till deltagare"
#: pretix/plugins/sendmail/signals.py:122
@@ -27056,7 +27056,7 @@ msgstr "Avbryt beställning"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:14
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:15
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:10
msgid "Scheduled emails are not sent as long as your ticket shop is offline."
msgid "Automated emails are not sent as long as your ticket shop is offline."
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:44
@@ -27107,7 +27107,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:6
#, fuzzy
#| msgid "Attendee email"
msgid "Scheduled email rules"
msgid "Automated email rules"
msgstr "Epost till deltagare"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:8
+3 -3
View File
@@ -24802,7 +24802,7 @@ msgstr[0] ""
msgstr[1] ""
#: pretix/plugins/sendmail/signals.py:99
msgid "Scheduled emails"
msgid "Automated emails"
msgstr ""
#: pretix/plugins/sendmail/signals.py:122
@@ -24880,7 +24880,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:14
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:15
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:10
msgid "Scheduled emails are not sent as long as your ticket shop is offline."
msgid "Automated emails are not sent as long as your ticket shop is offline."
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:44
@@ -24927,7 +24927,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:4
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:6
msgid "Scheduled email rules"
msgid "Automated email rules"
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:8
+3 -3
View File
@@ -29881,7 +29881,7 @@ msgstr[1] ""
#: pretix/plugins/sendmail/signals.py:99
#, fuzzy
#| msgid "Attendee email"
msgid "Scheduled emails"
msgid "Automated emails"
msgstr "Katılımcı e-postası"
#: pretix/plugins/sendmail/signals.py:122
@@ -29986,7 +29986,7 @@ msgstr "Yeni bir kullanıcı oluştur"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:14
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:15
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:10
msgid "Scheduled emails are not sent as long as your ticket shop is offline."
msgid "Automated emails are not sent as long as your ticket shop is offline."
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:44
@@ -30050,7 +30050,7 @@ msgstr "Veri seçimi"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:6
#, fuzzy
#| msgid "Attendee email"
msgid "Scheduled email rules"
msgid "Automated email rules"
msgstr "Katılımcı e-postası"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:8
+3 -3
View File
@@ -27634,7 +27634,7 @@ msgstr[1] ""
msgstr[2] ""
#: pretix/plugins/sendmail/signals.py:99
msgid "Scheduled emails"
msgid "Automated emails"
msgstr "Автоматизовані електронні листи"
#: pretix/plugins/sendmail/signals.py:122
@@ -27718,7 +27718,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:14
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:15
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:10
msgid "Scheduled emails are not sent as long as your ticket shop is offline."
msgid "Automated emails are not sent as long as your ticket shop is offline."
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:44
@@ -27768,7 +27768,7 @@ msgstr "Останній розрахунок графіка"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:4
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:6
msgid "Scheduled email rules"
msgid "Automated email rules"
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:8
+3 -3
View File
@@ -24809,7 +24809,7 @@ msgstr[0] ""
msgstr[1] ""
#: pretix/plugins/sendmail/signals.py:99
msgid "Scheduled emails"
msgid "Automated emails"
msgstr ""
#: pretix/plugins/sendmail/signals.py:122
@@ -24887,7 +24887,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:14
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:15
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:10
msgid "Scheduled emails are not sent as long as your ticket shop is offline."
msgid "Automated emails are not sent as long as your ticket shop is offline."
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:44
@@ -24934,7 +24934,7 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:4
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:6
msgid "Scheduled email rules"
msgid "Automated email rules"
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:8
@@ -28499,7 +28499,7 @@ msgstr[0] ""
#: pretix/plugins/sendmail/signals.py:99
#, fuzzy
#| msgid "Attendee email"
msgid "Scheduled emails"
msgid "Automated emails"
msgstr "观众Email"
#: pretix/plugins/sendmail/signals.py:122
@@ -28604,7 +28604,7 @@ msgstr "创建一个新用户"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:14
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:15
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:10
msgid "Scheduled emails are not sent as long as your ticket shop is offline."
msgid "Automated emails are not sent as long as your ticket shop is offline."
msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:44
@@ -28667,7 +28667,7 @@ msgstr "数据选择"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:6
#, fuzzy
#| msgid "Attendee email"
msgid "Scheduled email rules"
msgid "Automated email rules"
msgstr "观众Email"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:8

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