Compare commits

..
127 changed files with 27539 additions and 31819 deletions
+1 -16
View File
@@ -34,7 +34,6 @@ allow_multiple_entries boolean If ``true``, su
allow_entry_after_exit boolean If ``true``, subsequent scans of a ticket on this list are valid if the last scan of the ticket was an exit scan.
rules object Custom check-in logic. The contents of this field are currently not considered a stable API and modifications through the API are highly discouraged.
exit_all_at datetime Automatically check out (i.e. perform an exit scan) at this point in time. After this happened, this property will automatically be set exactly one day into the future. Note that this field is considered "internal configuration" and if you pull the list with ``If-Modified-Since``, the daily change in this field will not trigger a response.
addon_match boolean If ``true``, tickets on this list can be redeemed by scanning their parent ticket if this still leads to an unambiguous match.
===================================== ========================== =======================================================
.. versionchanged:: 3.9
@@ -54,10 +53,6 @@ addon_match boolean If ``true``, ti
The ``ends_after`` and ``expand`` query parameters have been added.
.. versionchanged:: 4.12
The ``addon_match`` attribute has been added.
Endpoints
---------
@@ -99,7 +94,6 @@ Endpoints
"allow_entry_after_exit": true,
"exit_all_at": null,
"rules": {},
"addon_match": false,
"auto_checkin_sales_channels": [
"pretixpos"
]
@@ -152,7 +146,6 @@ Endpoints
"allow_entry_after_exit": true,
"exit_all_at": null,
"rules": {},
"addon_match": false,
"auto_checkin_sales_channels": [
"pretixpos"
]
@@ -252,7 +245,6 @@ Endpoints
"subevent": null,
"allow_multiple_entries": false,
"allow_entry_after_exit": true,
"addon_match": false,
"auto_checkin_sales_channels": [
"pretixpos"
]
@@ -277,7 +269,6 @@ Endpoints
"subevent": null,
"allow_multiple_entries": false,
"allow_entry_after_exit": true,
"addon_match": false,
"auto_checkin_sales_channels": [
"pretixpos"
]
@@ -332,7 +323,6 @@ Endpoints
"subevent": null,
"allow_multiple_entries": false,
"allow_entry_after_exit": true,
"addon_match": false,
"auto_checkin_sales_channels": [
"pretixpos"
]
@@ -621,12 +611,8 @@ Order position endpoints
Tries to redeem an order position, identified by its internal ID, i.e. checks the attendee in. This endpoint
accepts a number of optional requests in the body.
**Tip:** Instead of an ID, you can also use the ``secret`` field as the lookup parameter. In this case, you should
always set ``untrusted_input=true`` as a query parameter to avoid security issues.
**Tip:** Instead of an ID, you can also use the ``secret`` field as the lookup parameter.
:query boolean untrusted_input: If set to true, the lookup parameter is **always** interpreted as a ``secret``, never
as an ``id``. This should be always set if you are passing through untrusted, scanned
data to avoid guessing of ticket IDs.
:<json boolean questions_supported: When this parameter is set to ``true``, handling of questions is supported. If
you do not implement question handling in your user interface, you **must**
set this to ``false``. In that case, questions will just be ignored. Defaults
@@ -753,7 +739,6 @@ Order position endpoints
* ``already_redeemed`` - Ticket already has been redeemed
* ``product`` - Tickets with this product may not be scanned at this device
* ``rules`` - Check-in prevented by a user-defined rule
* ``ambiguous`` - Multiple tickets match scan, rejected
In case of reason ``rules``, there might be an additional response field ``reason_explanation`` with a human-readable
description of the violated rules. However, that field can also be missing or be ``null``.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 274 KiB

After

Width:  |  Height:  |  Size: 236 KiB

+1 -18
View File
@@ -2,25 +2,8 @@
partition "data-based check" {
"Check based on local database" -down-> "Is addon_match set to true?"
"Check based on local database" --> "Is the order in status PAID or PENDING\nand is the position not canceled?"
--> if "" then
-down->[no] "Is the order in status PAID or PENDING\nand is the position not canceled?"
else
-right->[yes] "Build a list that includes the position\nas well as all its add-ons"
-down-> "Filter list for products that are part of the check-in list"
--> if "" then
-down->[one found] Proceed with the matching position
--> "Is the order in status PAID or PENDING\nand is the position not canceled?"
else
--> if "" then
-right->[none found] "Return error PRODUCT "
else
-down->[multiple found] Return error AMBIGUOUS
endif
endif
endif
"Is the order in status PAID or PENDING\nand is the position not canceled?" --> if "" then
-right->[no] "Return error CANCELED"
else
-down->[yes] "Is the product part of the check-in list?"
Binary file not shown.

Before

Width:  |  Height:  |  Size: 175 KiB

After

Width:  |  Height:  |  Size: 147 KiB

+1 -18
View File
@@ -19,25 +19,8 @@ else
endif
===CHECK=== -down-> "Is addon_match set to true?"
===CHECK=== -down-> "Is the order in status PAID or PENDING\nand is the position not canceled?"
--> if "" then
-down->[no] "Is the order in status PAID or PENDING\nand is the position not canceled?"
else
-right->[yes] "Build a list that includes the position\nas well as all its add-ons"
-down-> "Filter list for products that are part of the check-in list"
--> if "" then
-down->[one found] Proceed with the matching position
--> "Is the order in status PAID or PENDING\nand is the position not canceled?"
else
--> if "" then
-right->[none found] "Return error PRODUCT "
else
-down->[multiple found] Return error AMBIGUOUS
endif
endif
endif
"Is the order in status PAID or PENDING\nand is the position not canceled?" --> if "" then
-right->[no] "Return error CANCELED"
else
-down->[yes] "Is the product part of the check-in list?"
-1
View File
@@ -19,7 +19,6 @@ If you want to **create** a plugin, please go to the
certificates
digital
exhibitors
shipping
imported_secrets
webinar
presale-saml
-235
View File
@@ -1,235 +0,0 @@
Shipping
========
The shipping plugin provides a HTTP API that exposes the various layouts used to generate PDF badges.
Shipping address resource
-------------------------
The shipping address resource contains the following public fields:
.. rst-class:: rest-resource-table
===================================== ========================== =======================================================
Field Type Description
===================================== ========================== =======================================================
company string Customer company name
name string Customer name
street string Customer street
zipcode string Customer ZIP code
city string Customer city
country string Customer country code
state string Customer state (ISO 3166-2 code). Only supported in
AU, BR, CA, CN, MY, MX, and US.
gift boolean Request by customer to not disclose prices in the shipping
===================================== ========================== =======================================================
Shipping status resource
------------------------
The shipping status resource contains the following public fields:
.. rst-class:: rest-resource-table
===================================== ========================== =======================================================
Field Type Description
===================================== ========================== =======================================================
method integer Internal ID of shipping method
status string Status, one of ``"new"`` or ``"shipped"``
method_type string Method type, one of ``"ship"``, ``"online"``, or ``"collect"``
===================================== ========================== =======================================================
Print job resource
------------------
The print job resource contains the following public fields:
.. rst-class:: rest-resource-table
===================================== ========================== =======================================================
Field Type Description
===================================== ========================== =======================================================
code string Order code of the ticket order
event string Event slug
status string Status, one of ``"new"`` or ``"shipped"``
method string Method type, one of ``"ship"``, ``"online"``, or ``"collect"``
===================================== ========================== =======================================================
Endpoints
---------
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/orders/(code)/shippingaddress/
Returns the shipping address of an order
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/bigevents/events/democon/orders/ABC12/shippingaddress/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: text/javascript
{
"company": "ACME Corp",
"name": "John Doe",
"street": "Sesame Street 12\nAp. 5",
"zipcode": "12345",
"city": "Berlin",
"country": "DE",
"state": "",
"gift": false
}
:param organizer: The ``slug`` field of a valid organizer
:param event: The ``slug`` field of a valid event
:param order: The ``code`` field of a valid order
:statuscode 200: no error
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer does not exist **or** you have no permission to view it.
:statuscode 404: The order does not exist or no shipping address is attached.
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/orders/(code)/shippingaddress/
Returns the shipping status of an order
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/bigevents/events/democon/orders/ABC12/shippingstatus/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: text/javascript
{
"method": 23,
"method_type": "ship",
"status": "new"
}
:param organizer: The ``slug`` field of a valid organizer
:param event: The ``slug`` field of a valid event
:param order: The ``code`` field of a valid order
:statuscode 200: no error
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer does not exist **or** you have no permission to view it.
:statuscode 404: The order does not exist or no shipping address is attached.
.. http:get:: /api/v1/organizers/(organizer)/printjobs/
Returns a list of ticket orders, only useful with some query filters
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/bigevents/printjobs/?method=ship&status=new HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: text/javascript
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"event": "democon",
"order": "ABC12",
"method": "ship",
"status": "new"
}
]
}
:query string method: Filter by response field ``method`` (can be passed multiple times)
:query string status: Filter by response field ``status``
:query string event: Filter by response field ``event``
:param organizer: The ``slug`` field of a valid organizer
:param event: The ``slug`` field of a valid event
:statuscode 200: no error
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer does not exist **or** you have no permission to view it.
.. http:get:: /api/v1/organizers/(organizer)/printjobs/poll/
Returns the PDF file for the next job to print.
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/bigevents/printjobs/poll/?method=ship&status=new 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/pdf
X-Pretix-Order-Code: ABC12
...
:query string method: Filter by response field ``method`` (can be passed multiple times)
:query string status: Filter by response field ``status``
:query string event: Filter by response field ``event``
:param organizer: The ``slug`` field of a valid organizer
:param event: The ``slug`` field of a valid event
:statuscode 200: no error
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer does not exist **or** you have no permission to view it.
.. http:post:: /api/v1/organizers/(organizer)/printjobs/(order)/ack/
Change an order's status to "shipped".
**Example request**:
.. sourcecode:: http
POST /api/v1/organizers/bigevents/printjobs/ABC12/ack/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
**Example response**:
.. sourcecode:: http
HTTP/1.1 204 No Content
Vary: Accept
:param organizer: The ``slug`` field of a valid organizer
:param event: The ``slug`` field of a valid event
:param order: The ``code`` field of a valid order
:statuscode 200: no error
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer does not exist **or** you have no permission to view it.
:statuscode 404: The order does not exist.
+1 -2
View File
@@ -78,7 +78,7 @@ Synchronization setting any
----------------------------------------------- ----------------------------------- ----------------------------------------------------------------------- -----------------------------------------------------------------------
Ticket secrets any Random Signed Random Signed
=============================================== =================================== =================================== =================================== ================================= =====================================
Scenario supported on platforms Android, Desktop, iOS Android, Desktop, iOS Android, Desktop Android, Desktop, iOS Android, Desktop, iOS
Scenario supported on platforms Android, Desktop, iOS Android, Desktop, iOS Android, Desktop Android, Desktop Android, Desktop
Synchronization speed for large data sets slow slow fast fast
Tickets can be scanned yes yes yes no yes
Ticket is valid after sale immediately next sync (~5 minutes) immediately never immediately
@@ -90,7 +90,6 @@ Name and seat visible on scanner yes
Order-specific check-in attention flag yes yes yes (except directly after sale) n/a no
Ticket search by order code or name yes yes yes (except directly after sale) no no
Check-in statistics on scanner yes yes mostly accurate no no
Support for add-on check-in with main ticket yes yes yes (except directly after sale) no no
=============================================== =================================== =================================== =================================== ================================= =====================================
.. _EdDSA: https://en.wikipedia.org/wiki/EdDSA#Ed25519
-4
View File
@@ -135,10 +135,6 @@ Alternatively, you can select one or more categories to be shown::
<pretix-widget event="https://pretix.eu/demo/democon/" categories="12,25"></pretix-widget>
Or variation IDs::
<pretix-widget event="https://pretix.eu/demo/democon/" variations="15,2,68"></pretix-widget>
Multi-event selection
---------------------
-2
View File
@@ -14,8 +14,6 @@ recursive-include pretix/plugins/manualpayment/templates *
recursive-include pretix/plugins/manualpayment/static *
recursive-include pretix/plugins/paypal/templates *
recursive-include pretix/plugins/paypal/static *
recursive-include pretix/plugins/paypal2/templates *
recursive-include pretix/plugins/paypal2/static *
recursive-include pretix/plugins/pretixdroid/templates *
recursive-include pretix/plugins/pretixdroid/static *
recursive-include pretix/plugins/sendmail/templates *
+1 -1
View File
@@ -19,4 +19,4 @@
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
# <https://www.gnu.org/licenses/>.
#
__version__ = "4.12.0.dev0"
__version__ = "4.11.0.dev0"
+1 -1
View File
@@ -37,7 +37,7 @@ class CheckinListSerializer(I18nAwareModelSerializer):
model = CheckinList
fields = ('id', 'name', 'all_products', 'limit_products', 'subevent', 'checkin_count', 'position_count',
'include_pending', 'auto_checkin_sales_channels', 'allow_multiple_entries', 'allow_entry_after_exit',
'rules', 'exit_all_at', 'addon_match')
'rules', 'exit_all_at')
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
+15 -89
View File
@@ -25,7 +25,6 @@ from django.core.exceptions import ValidationError
from django.db import transaction
from django.db.models import (
Count, Exists, F, Max, OrderBy, OuterRef, Prefetch, Q, Subquery,
prefetch_related_objects,
)
from django.db.models.functions import Coalesce
from django.http import Http404
@@ -281,7 +280,7 @@ class CheckinListPositionViewSet(viewsets.ReadOnlyModelViewSet):
serializer_class = CheckinListOrderPositionSerializer
queryset = OrderPosition.all.none()
filter_backends = (ExtendedBackend, RichOrderingFilter)
ordering = (F('attendee_name_cached').asc(nulls_last=True), 'positionid')
ordering = ('attendee_name_cached', 'positionid')
ordering_fields = (
'order__code', 'order__datetime', 'positionid', 'attendee_name',
'last_checked_in', 'order__email',
@@ -409,13 +408,6 @@ class CheckinListPositionViewSet(viewsets.ReadOnlyModelViewSet):
raise ValidationError("Invalid check-in type.")
ignore_unpaid = bool(self.request.data.get('ignore_unpaid', False))
nonce = self.request.data.get('nonce')
untrusted_input = (
self.request.GET.get('untrusted_input', '') not in ('0', 'false', 'False', '')
or (isinstance(self.request.auth, Device) and 'pretixscan' in (self.request.auth.software_brand or '').lower())
)
if not self.checkinlist.all_products:
prefetch_related_objects([self.checkinlist], 'limit_products')
if 'datetime' in self.request.data:
dt = DateTimeField().to_internal_value(self.request.data.get('datetime'))
@@ -435,32 +427,19 @@ class CheckinListPositionViewSet(viewsets.ReadOnlyModelViewSet):
raw_barcode_for_checkin = None
from_revoked_secret = False
# 1. Gather a list of positions that could be the one we looking fore, either from their ID, secret or
# parent secret
queryset = self.get_queryset(ignore_status=True, ignore_products=True).order_by(
F('addon_to').asc(nulls_first=True)
)
q = Q(secret=self.kwargs['pk'])
if self.checkinlist.addon_match:
q |= Q(addon_to__secret=self.kwargs['pk'])
if self.kwargs['pk'].isnumeric() and not untrusted_input:
q |= Q(pk=self.kwargs['pk'])
op_candidates = list(queryset.filter(q))
if not op_candidates and '+' in self.kwargs['pk']:
# In application/x-www-form-urlencoded, you can encodes space ' ' with '+' instead of '%20'.
# `id`, however, is part of a path where this technically is not allowed. Old versions of our
# scan apps still do it, so we try work around it!
q = Q(secret=self.kwargs['pk'].replace('+', ' '))
if self.checkinlist.addon_match:
q |= Q(addon_to__secret=self.kwargs['pk'].replace('+', ' '))
op_candidates = list(queryset.filter(q))
# 2. Handle the "nothing found" case: Either it's really a bogus secret that we don't know (-> error), or it
# might be a revoked one that we actually know (-> error, but with better error message and logging and
# with respecting the force option).
if not op_candidates:
try:
queryset = self.get_queryset(ignore_status=True, ignore_products=True)
if self.kwargs['pk'].isnumeric():
op = queryset.get(Q(pk=self.kwargs['pk']) | Q(secret=self.kwargs['pk']))
else:
# In application/x-www-form-urlencoded, you can encodes space ' ' with '+' instead of '%20'.
# `id`, however, is part of a path where this technically is not allowed. Old versions of our
# scan apps still do it, so we try work around it!
try:
op = queryset.get(secret=self.kwargs['pk'])
except OrderPosition.DoesNotExist:
op = queryset.get(secret=self.kwargs['pk'].replace('+', ' '))
except OrderPosition.DoesNotExist:
revoked_matches = list(self.request.event.revoked_secrets.filter(secret=self.kwargs['pk']))
if len(revoked_matches) == 0:
self.request.event.log_action('pretix.event.checkin.unknown', data={
@@ -520,9 +499,7 @@ class CheckinListPositionViewSet(viewsets.ReadOnlyModelViewSet):
'require_attention': False,
}, status=404)
elif revoked_matches and force:
op_candidates = [revoked_matches[0].position]
if self.checkinlist.addon_match:
op_candidates += list(revoked_matches[0].position.addons.all())
op = revoked_matches[0].position
raw_barcode_for_checkin = self.kwargs['pk']
from_revoked_secret = True
else:
@@ -547,56 +524,6 @@ class CheckinListPositionViewSet(viewsets.ReadOnlyModelViewSet):
'position': CheckinListOrderPositionSerializer(op, context=self.get_serializer_context()).data
}, status=400)
# 3. Handle the "multiple options found" case: Except for the unlikely case of a secret being also a valid primary
# key on the same list, we're probably dealing with the ``addon_match`` case here and need to figure out
# which add-on has the right product.
if len(op_candidates) > 1:
if self.checkinlist.addon_match and not self.checkinlist.all_products:
op_candidates_matching_product = [
op for op in op_candidates if op.item_id in {i.pk for i in self.checkinlist.limit_products.all()}
]
else:
op_candidates_matching_product = op_candidates
if len(op_candidates_matching_product) == 0:
# None of the found add-ons has the correct product, too bad! We could just error out here, but
# instead we just continue with *any* product and have it rejected by the check in perform_checkin.
# This has the advantage of a better error message.
op_candidates = [op_candidates[0]]
elif len(op_candidates_matching_product) > 1:
# It's still ambiguous, we'll error out.
# We choose the first match (regardless of product) for the logging since it's most likely to be the
# base product according to our order_by above.
op = op_candidates[0]
op.order.log_action('pretix.event.checkin.denied', data={
'position': op.id,
'positionid': op.positionid,
'errorcode': Checkin.REASON_AMBIGUOUS,
'reason_explanation': None,
'force': force,
'datetime': dt,
'type': type,
'list': self.checkinlist.pk
}, user=self.request.user, auth=self.request.auth)
Checkin.objects.create(
position=op,
successful=False,
error_reason=Checkin.REASON_AMBIGUOUS,
error_explanation=None,
**common_checkin_args,
)
return Response({
'status': 'error',
'reason': Checkin.REASON_AMBIGUOUS,
'reason_explanation': None,
'require_attention': op.item.checkin_attention or op.order.checkin_attention,
'position': CheckinListOrderPositionSerializer(op, context=self.get_serializer_context()).data
}, status=400)
else:
op_candidates = op_candidates_matching_product
op = op_candidates[0]
# 5. Pre-validate all incoming answers, handle file upload
given_answers = {}
if 'answers' in self.request.data:
aws = self.request.data.get('answers')
@@ -610,7 +537,6 @@ class CheckinListPositionViewSet(viewsets.ReadOnlyModelViewSet):
except ValidationError:
pass
# 6. Pass to our actual check-in logic
with language(self.request.event.settings.locale):
try:
perform_checkin(
+2 -5
View File
@@ -475,11 +475,8 @@ def base_placeholders(sender, **kwargs):
),
SimpleFunctionalMailTextPlaceholder(
'event_admission_time', ['event_or_subevent'],
lambda event_or_subevent:
date_format(event_or_subevent.date_admission.astimezone(event_or_subevent.timezone), 'TIME_FORMAT')
if event_or_subevent.date_admission
else '',
lambda event: date_format(event.date_admission.astimezone(event.timezone), 'TIME_FORMAT') if event.date_admission else '',
lambda event_or_subevent: date_format(event_or_subevent.date_admission, 'TIME_FORMAT') if event_or_subevent.date_admission else '',
lambda event: date_format(event.date_admission, 'TIME_FORMAT') if event.date_admission else '',
),
SimpleFunctionalMailTextPlaceholder(
'subevent', ['waiting_list_entry', 'event'],
-1
View File
@@ -23,7 +23,6 @@ from .answers import * # noqa
from .dekodi import * # noqa
from .events import * # noqa
from .invoices import * # noqa
from .items import * # noqa
from .json import * # noqa
from .mail import * # noqa
from .orderlist import * # noqa
-222
View File
@@ -1,222 +0,0 @@
#
# This file is part of pretix (Community Edition).
#
# Copyright (C) 2014-2020 Raphael Michel and contributors
# Copyright (C) 2020-2021 rami.io GmbH and contributors
#
# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General
# Public License as published by the Free Software Foundation in version 3 of the License.
#
# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are
# applicable granting you additional permissions and placing additional restrictions on your usage of this software.
# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive
# this file, see <https://pretix.eu/about/en/license>.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
# <https://www.gnu.org/licenses/>.
#
from django.db.models import Prefetch
from django.dispatch import receiver
from django.utils.formats import date_format
from django.utils.translation import gettext_lazy as _
from openpyxl.styles import Alignment
from openpyxl.utils import get_column_letter
from ...helpers.safe_openpyxl import SafeCell
from ..channels import get_all_sales_channels
from ..exporter import ListExporter
from ..models import ItemMetaValue
from ..signals import register_data_exporters
def _max(a1, a2):
if a1 and a2:
return max(a1, a2)
return a1 or a2
def _min(a1, a2):
if a1 and a2:
return min(a1, a2)
return a1 or a2
class ItemDataExporter(ListExporter):
identifier = 'itemdata'
verbose_name = _('Product data')
def iterate_list(self, form_data):
locales = self.event.settings.locales
scs = get_all_sales_channels()
header = [
_("Product ID"),
_("Variation ID"),
_("Product category"),
_("Internal name"),
]
for l in locales:
header.append(
_("Item name") + f" ({l})"
)
for l in locales:
header.append(
_("Variation") + f" ({l})"
)
header += [
_("Active"),
_("Sales channels"),
_("Default price"),
_("Free price input"),
_("Sales tax"),
_("Is an admission ticket"),
_("Generate tickets"),
_("Waiting list"),
_("Available from"),
_("Available until"),
_("This product can only be bought using a voucher."),
_("This product will only be shown if a voucher matching the product is redeemed."),
_("Buying this product requires approval"),
_("Only sell this product as part of a bundle"),
_("Allow product to be canceled or changed"),
_("Minimum amount per order"),
_("Maximum amount per order"),
_("Requires special attention"),
_("Original price"),
_("This product is a gift card"),
_("Require a valid membership"),
_("Hide without a valid membership"),
]
props = list(self.event.item_meta_properties.all())
for p in props:
header.append(p.name)
if form_data["_format"] == "xlsx":
row = []
for h in header:
c = SafeCell(self.__ws, value=h)
c.alignment = Alignment(wrap_text=True, vertical='top')
row.append(c)
else:
row = header
yield row
for i in self.event.items.prefetch_related(
'variations',
Prefetch(
'meta_values',
ItemMetaValue.objects.select_related('property'),
to_attr='meta_values_cached'
)
).select_related('category', 'tax_rule'):
m = i.meta_data
vars = list(i.variations.all())
if vars:
for v in vars:
row = [
i.pk,
v.pk,
str(i.category) if i.category else "",
i.internal_name or "",
]
for l in locales:
row.append(i.name.localize(l))
for l in locales:
row.append(v.value.localize(l))
row += [
_("Yes") if i.active and v.active else "",
", ".join([str(sn.verbose_name) for s, sn in scs.items() if s in i.sales_channels and s in v.sales_channels]),
v.default_price or i.default_price,
_("Yes") if i.free_price else "",
str(i.tax_rule) if i.tax_rule else "",
_("Yes") if i.admission else "",
_("Yes") if i.generate_tickets else (_("Default") if i.generate_tickets is None else ""),
_("Yes") if i.allow_waitinglist else "",
date_format(_max(i.available_from, v.available_from).astimezone(self.timezone),
"SHORT_DATETIME_FORMAT") if i.available_from or v.available_from else "",
date_format(_min(i.available_until, v.available_until).astimezone(self.timezone),
"SHORT_DATETIME_FORMAT") if i.available_until or v.available_until else "",
_("Yes") if i.require_voucher else "",
_("Yes") if i.hide_without_voucher or v.hide_without_voucher else "",
_("Yes") if i.require_approval or v.require_approval else "",
_("Yes") if i.require_bundling else "",
_("Yes") if i.allow_cancel else "",
i.min_per_order if i.min_per_order is not None else "",
i.max_per_order if i.max_per_order is not None else "",
_("Yes") if i.checkin_attention else "",
v.original_price or i.original_price or "",
_("Yes") if i.issue_giftcard else "",
_("Yes") if i.require_membership or v.require_membership else "",
_("Yes") if i.require_membership_hidden or v.require_membership_hidden else "",
]
row += [
m.get(p.name, '') for p in props
]
yield row
else:
row = [
i.pk,
"",
str(i.category) if i.category else "",
i.internal_name or "",
]
for l in locales:
row.append(i.name.localize(l))
for l in locales:
row.append("")
row += [
_("Yes") if i.active else "",
", ".join([str(sn.verbose_name) for s, sn in scs.items() if s in i.sales_channels]),
i.default_price,
_("Yes") if i.free_price else "",
str(i.tax_rule) if i.tax_rule else "",
_("Yes") if i.admission else "",
_("Yes") if i.generate_tickets else (_("Default") if i.generate_tickets is None else ""),
_("Yes") if i.allow_waitinglist else "",
date_format(i.available_from.astimezone(self.timezone),
"SHORT_DATETIME_FORMAT") if i.available_from else "",
date_format(i.available_until.astimezone(self.timezone),
"SHORT_DATETIME_FORMAT") if i.available_until else "",
_("Yes") if i.require_voucher else "",
_("Yes") if i.hide_without_voucher else "",
_("Yes") if i.require_approval else "",
_("Yes") if i.require_bundling else "",
_("Yes") if i.allow_cancel else "",
i.min_per_order if i.min_per_order is not None else "",
i.max_per_order if i.max_per_order is not None else "",
_("Yes") if i.checkin_attention else "",
i.original_price or "",
_("Yes") if i.issue_giftcard else "",
_("Yes") if i.require_membership else "",
_("Yes") if i.require_membership_hidden else "",
]
row += [
m.get(p.name, '') for p in props
]
yield row
def get_filename(self):
return '{}_products'.format(self.events.first().organizer.slug)
def prepare_xlsx_sheet(self, ws):
self.__ws = ws
ws.freeze_panes = 'A1'
ws.column_dimensions['C'].width = 25
ws.column_dimensions['D'].width = 25
for i in range(len(self.event.settings.locales)):
ws.column_dimensions[get_column_letter(5 + 2 * i + 0)].width = 25
ws.column_dimensions[get_column_letter(5 + 2 * i + 1)].width = 25
ws.column_dimensions[get_column_letter(5 + 2 * len(self.event.settings.locales) + 1)].width = 25
ws.row_dimensions[1].height = 40
@receiver(register_data_exporters, dispatch_uid="exporter_itemdata")
def register_itemdata_exporter(sender, **kwargs):
return ItemDataExporter
+1 -1
View File
@@ -253,7 +253,7 @@ class NamePartsFormField(forms.MultiValueField):
if self.require_all_fields and not all(v for v in value):
raise forms.ValidationError(self.error_messages['incomplete'], code='required')
if sum(len(v) for v in value.values() if v) > 250:
if sum(len(v) for v in value if v) > 250:
raise forms.ValidationError(_('Please enter a shorter name.'), code='max_length')
return value
@@ -1,33 +0,0 @@
# Generated by Django 3.2.12 on 2022-06-15 08:10
import django.db.models.deletion
import i18nfield.fields
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('pretixbase', '0216_checkin_forced_sent'),
]
operations = [
migrations.CreateModel(
name='OrganizerFooterLink',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False)),
('label', i18nfield.fields.I18nCharField(max_length=200)),
('url', models.URLField()),
('organizer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='footer_links', to='pretixbase.organizer')),
],
),
migrations.CreateModel(
name='EventFooterLink',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False)),
('label', i18nfield.fields.I18nCharField(max_length=200)),
('url', models.URLField()),
('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='footer_links', to='pretixbase.event')),
],
),
]
@@ -1,18 +0,0 @@
# Generated by Django 3.2.2 on 2022-06-29 17:37
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('pretixbase', '0217_eventfooterlink_organizerfooterlink'),
]
operations = [
migrations.AddField(
model_name='checkinlist',
name='addon_match',
field=models.BooleanField(default=False),
),
]
-8
View File
@@ -56,12 +56,6 @@ class CheckinList(LoggedModel):
default=False,
help_text=_('With this option, people will be able to check in even if the '
'order has not been paid.'))
addon_match = models.BooleanField(
verbose_name=_('Allow checking in add-on tickets by scanning the main ticket'),
default=False,
help_text=_('A scan will only be possible if the check-in list is configured such that there is always exactly '
'one matching add-on ticket. Ambiguous scans will be rejected..')
)
gates = models.ManyToManyField(
'Gate', verbose_name=_("Gates"), blank=True,
help_text=_("Does not have any effect for the validation of tickets, only for the automatic configuration of "
@@ -264,7 +258,6 @@ class Checkin(models.Model):
REASON_REVOKED = 'revoked'
REASON_INCOMPLETE = 'incomplete'
REASON_ALREADY_REDEEMED = 'already_redeemed'
REASON_AMBIGUOUS = 'ambiguous'
REASON_ERROR = 'error'
REASONS = (
(REASON_CANCELED, _('Order canceled')),
@@ -275,7 +268,6 @@ class Checkin(models.Model):
(REASON_INCOMPLETE, _('Information required')),
(REASON_ALREADY_REDEEMED, _('Ticket already used')),
(REASON_PRODUCT, _('Ticket type not allowed here')),
(REASON_AMBIGUOUS, _('Ticket code is ambiguous on list')),
(REASON_ERROR, _('Server error')),
)
+1 -31
View File
@@ -608,14 +608,11 @@ class Event(EventMixin, LoggedModel):
return super().presale_has_ended
def delete_all_orders(self, really=False):
from .orders import (
OrderFee, OrderPayment, OrderPosition, OrderRefund, Transaction,
)
from .orders import OrderFee, OrderPayment, OrderPosition, OrderRefund
if not really:
raise TypeError("Pass really=True as a parameter.")
Transaction.objects.filter(order__event=self).delete()
OrderPosition.all.filter(order__event=self, addon_to__isnull=False).delete()
OrderPosition.all.filter(order__event=self).delete()
OrderFee.objects.filter(order__event=self).delete()
@@ -721,11 +718,6 @@ class Event(EventMixin, LoggedModel):
self.save()
self.log_action('pretix.object.cloned', data={'source': other.slug, 'source_id': other.pk})
for fl in EventFooterLink.objects.filter(event=other):
fl.pk = None
fl.event = self
fl.save(force_insert=True)
tax_map = {}
for t in other.tax_rules.all():
tax_map[t.pk] = t
@@ -1620,25 +1612,3 @@ class SubEventMetaValue(LoggedModel):
super().save(*args, **kwargs)
if self.subevent:
self.subevent.event.cache.clear()
class EventFooterLink(models.Model):
"""
A footer link assigned to an event.
"""
event = models.ForeignKey('Event', on_delete=models.CASCADE, related_name='footer_links')
label = I18nCharField(
max_length=200,
verbose_name=_("Link text"),
)
url = models.URLField(
verbose_name=_("Link URL"),
)
def delete(self, *args, **kwargs):
super().delete(*args, **kwargs)
self.event.cache.clear()
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
self.event.cache.clear()
+2 -3
View File
@@ -843,7 +843,7 @@ class Order(LockModel, LoggedModel):
if terms:
term_last = min(terms)
else:
return None
term_last = None
else:
term_last = term_last.datetime(self.event).date()
term_last = make_aware(datetime.combine(
@@ -1588,7 +1588,7 @@ class OrderPayment(models.Model):
if status_change:
self.order.create_transactions()
def fail(self, info=None, user=None, auth=None, log_data=None):
def fail(self, info=None, user=None, auth=None):
"""
Marks the order as failed and sets info to ``info``, but only if the order is in ``created`` or ``pending``
state. This is equivalent to setting ``state`` to ``OrderPayment.PAYMENT_STATE_FAILED`` and logging a failure,
@@ -1616,7 +1616,6 @@ class OrderPayment(models.Model):
'local_id': self.local_id,
'provider': self.provider,
'info': info,
'data': log_data,
}, user=user, auth=auth)
def confirm(self, count_waitinglist=True, send_mail=True, force=False, user=None, auth=None, mail_text='',
-23
View File
@@ -46,7 +46,6 @@ from django.utils.crypto import get_random_string
from django.utils.functional import cached_property
from django.utils.timezone import get_current_timezone, make_aware, now
from django.utils.translation import gettext_lazy as _
from i18nfield.fields import I18nCharField
from pretix.base.models.base import LoggedModel
from pretix.base.validators import OrganizerSlugBanlistValidator
@@ -465,25 +464,3 @@ class TeamAPIToken(models.Model):
return self.get_events_with_any_permission()
else:
return self.team.organizer.events.none()
class OrganizerFooterLink(models.Model):
"""
A footer link assigned to an organizer.
"""
organizer = models.ForeignKey('Organizer', on_delete=models.CASCADE, related_name='footer_links')
label = I18nCharField(
max_length=200,
verbose_name=_("Link text"),
)
url = models.URLField(
verbose_name=_("Link URL"),
)
def delete(self, *args, **kwargs):
super().delete(*args, **kwargs)
self.organizer.cache.clear()
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
self.organizer.cache.clear()
+1 -2
View File
@@ -831,10 +831,9 @@ class Renderer:
textColor=Color(o['color'][0] / 255, o['color'][1] / 255, o['color'][2] / 255),
alignment=align_map[o['align']]
)
# add an almost-invisible space &hairsp; after hyphens as word-wrap in ReportLab only works on space chars
text = conditional_escape(
self._get_text_content(op, order, o) or "",
).replace("\n", "<br/>\n").replace("-", "-&hairsp;")
).replace("\n", "<br/>\n")
# reportlab does not support RTL, ligature-heavy scripts like Arabic. Therefore, we use ArabicReshaper
# to resolve all ligatures and python-bidi to switch RTL texts.
+2 -2
View File
@@ -143,8 +143,8 @@ class Sig1TicketSecretGenerator(BaseTicketSecretGenerator):
The resulting string is REVERSED, to avoid all secrets of same length beginning with the same 10
characters, which would make it impossible to search for secrets manually.
"""
verbose_name = _('pretix signature scheme 1 (for very large events, changes semantics of offline scanning '
'please refer to documentation or support for details)')
verbose_name = _('pretix signature scheme 1 (for very large events, does not work with pretixSCAN on iOS and '
'changes semantics of offline scanning please refer to documentation or support for details)')
identifier = 'pretix_sig1'
use_revocation_list = True
-5
View File
@@ -2304,11 +2304,6 @@ class OrderChangeManager:
# Do nothing
return
# Clear prefetched objects cache of order. We're going to modify the positions and fees and we have no guarantee
# that every operation tuple points to a position/fee instance that has been fetched from the same object cache,
# so it's dangerous to keep the cache around.
self.order._prefetched_objects_cache = {}
# finally, incorporate difference in payment fees
self._payment_fee_diff()
@@ -96,7 +96,6 @@ ALLOWED_ATTRIBUTES = {
'div': ['class'],
'p': ['class'],
'span': ['class', 'title'],
'ol': ['start'],
# Update doc/user/markdown.rst if you change this!
}
+1 -9
View File
@@ -22,10 +22,9 @@
from datetime import datetime, timedelta
from django import forms
from django.core.exceptions import ValidationError
from django.urls import reverse
from django.utils.timezone import get_current_timezone, make_aware, now
from django.utils.translation import gettext_lazy as _, pgettext_lazy
from django.utils.translation import pgettext_lazy
from django_scopes.forms import (
SafeModelChoiceField, SafeModelMultipleChoiceField,
)
@@ -110,7 +109,6 @@ class CheckinListForm(forms.ModelForm):
'rules',
'gates',
'exit_all_at',
'addon_match',
]
widgets = {
'limit_products': forms.CheckboxSelectMultiple(attrs={
@@ -132,12 +130,6 @@ class CheckinListForm(forms.ModelForm):
def clean(self):
d = super().clean()
d['rules'] = CheckinList.validate_rules(d.get('rules'))
if d.get('addon_match') and d.get('all_products'):
raise ValidationError(_('If you allow checking in add-on tickets by scanning the main ticket, you must '
'select a specific set of products for this check-in list, only including the '
'possible add-on products.'))
return d
+2 -26
View File
@@ -41,9 +41,7 @@ from django.conf import settings
from django.core.exceptions import ValidationError
from django.core.validators import validate_email
from django.db.models import Prefetch, Q, prefetch_related_objects
from django.forms import (
CheckboxSelectMultiple, formset_factory, inlineformset_factory,
)
from django.forms import CheckboxSelectMultiple, formset_factory
from django.urls import reverse
from django.utils.functional import cached_property
from django.utils.html import escape
@@ -60,7 +58,7 @@ from pretix.base.channels import get_all_sales_channels
from pretix.base.email import get_available_placeholders
from pretix.base.forms import I18nModelForm, PlaceholderValidator, SettingsForm
from pretix.base.models import Event, Organizer, TaxRule, Team
from pretix.base.models.event import EventFooterLink, EventMetaValue, SubEvent
from pretix.base.models.event import EventMetaValue, SubEvent
from pretix.base.reldate import RelativeDateField, RelativeDateTimeField
from pretix.base.settings import (
PERSON_NAME_SCHEMES, PERSON_NAME_TITLE_GROUPS, validate_event_settings,
@@ -1486,25 +1484,3 @@ ConfirmTextFormset = formset_factory(
formset=BaseConfirmTextFormSet,
can_order=True, can_delete=True, extra=0
)
class EventFooterLinkForm(I18nModelForm):
class Meta:
model = EventFooterLink
fields = ('label', 'url')
class BaseEventFooterLinkFormSet(I18nFormSetMixin, forms.BaseInlineFormSet):
def __init__(self, *args, **kwargs):
event = kwargs.pop('event', None)
if event:
kwargs['locales'] = event.settings.get('locales')
super().__init__(*args, **kwargs)
EventFooterLinkFormset = inlineformset_factory(
Event, EventFooterLink,
EventFooterLinkForm,
formset=BaseEventFooterLinkFormSet,
can_order=False, can_delete=True, extra=0
)
+1 -25
View File
@@ -39,13 +39,12 @@ from django import forms
from django.conf import settings
from django.core.exceptions import ValidationError
from django.db.models import Q
from django.forms import inlineformset_factory
from django.forms.utils import ErrorDict
from django.utils.crypto import get_random_string
from django.utils.safestring import mark_safe
from django.utils.translation import gettext_lazy as _, pgettext_lazy
from django_scopes.forms import SafeModelMultipleChoiceField
from i18nfield.forms import I18nFormField, I18nFormSetMixin, I18nTextarea
from i18nfield.forms import I18nFormField, I18nTextarea
from phonenumber_field.formfields import PhoneNumberField
from pytz import common_timezones
@@ -61,7 +60,6 @@ from pretix.base.models import (
Customer, Device, EventMetaProperty, Gate, GiftCard, Membership,
MembershipType, Organizer, Team,
)
from pretix.base.models.organizer import OrganizerFooterLink
from pretix.base.settings import PERSON_NAME_SCHEMES, PERSON_NAME_TITLE_GROUPS
from pretix.control.forms import ExtFileField, SplitDateTimeField
from pretix.control.forms.event import (
@@ -684,25 +682,3 @@ class MembershipUpdateForm(forms.ModelForm):
titles=self.instance.customer.organizer.settings.name_scheme_titles,
label=_('Attendee name'),
)
class OrganizerFooterLinkForm(I18nModelForm):
class Meta:
model = OrganizerFooterLink
fields = ('label', 'url')
class BaseOrganizerFooterLinkFormSet(I18nFormSetMixin, forms.BaseInlineFormSet):
def __init__(self, *args, **kwargs):
organizer = kwargs.pop('organizer', None)
if organizer:
kwargs['locales'] = organizer.settings.get('locales')
super().__init__(*args, **kwargs)
OrganizerFooterLinkFormset = inlineformset_factory(
Organizer, OrganizerFooterLink,
OrganizerFooterLinkForm,
formset=BaseOrganizerFooterLinkFormSet,
can_order=False, can_delete=True, extra=0
)
+1 -3
View File
@@ -314,7 +314,6 @@ def pretixcontrol_logentry_display(sender: Event, logentry: LogEntry, **kwargs):
'pretix.object.cloned': _('This object has been created by cloning.'),
'pretix.organizer.changed': _('The organizer has been changed.'),
'pretix.organizer.settings': _('The organizer settings have been changed.'),
'pretix.organizer.footerlinks.changed': _('The footer links have been changed.'),
'pretix.giftcards.acceptance.added': _('Gift card acceptance for another organizer has been added.'),
'pretix.giftcards.acceptance.removed': _('Gift card acceptance for another organizer has been removed.'),
'pretix.webhook.created': _('The webhook has been created.'),
@@ -366,7 +365,7 @@ def pretixcontrol_logentry_display(sender: Event, logentry: LogEntry, **kwargs):
'pretix.event.order.payment.changed': _('A new payment {local_id} has been started instead of the previous one.'),
'pretix.event.order.email.sent': _('An unidentified type email has been sent.'),
'pretix.event.order.email.error': _('Sending of an email has failed.'),
'pretix.event.order.email.attachments.skipped': _('The email has been sent without attached tickets since they '
'pretix.event.order.email.attachments.skipped': _('The email has been sent without attachments since they '
'would have been too large to be likely to arrive.'),
'pretix.event.order.email.custom_sent': _('A custom email has been sent.'),
'pretix.event.order.position.email.custom_sent': _('A custom email has been sent to an attendee.'),
@@ -469,7 +468,6 @@ def pretixcontrol_logentry_display(sender: Event, logentry: LogEntry, **kwargs):
'pretix.event.testmode.deactivated': _('The test mode has been disabled.'),
'pretix.event.added': _('The event has been created.'),
'pretix.event.changed': _('The event details have been changed.'),
'pretix.event.footerlinks.changed': _('The footer links have been changed.'),
'pretix.event.question.option.added': _('An answer option has been added to the question.'),
'pretix.event.question.option.deleted': _('An answer option has been removed from the question.'),
'pretix.event.question.option.changed': _('An answer option has been changed.'),
@@ -48,14 +48,16 @@
Make sure to always use the latest version of our scanning apps for these options to work.
{% endblocktrans %}
<br>
{% blocktrans trimmed %}
If you make use of these advanced options, we recommend using our Android and Desktop apps.
{% endblocktrans %}
<strong>
{% blocktrans trimmed %}
If you make use of these advanced options, we recommend using our Android and Desktop apps.
Custom check-in rules do not work offline with our iOS scanning app.
{% endblocktrans %}
</strong>
</div>
{% bootstrap_field form.allow_multiple_entries layout="control" %}
{% bootstrap_field form.allow_entry_after_exit layout="control" %}
{% bootstrap_field form.addon_match layout="control" %}
{% bootstrap_field form.exit_all_at layout="control" %}
{% bootstrap_field form.auto_checkin_sales_channels layout="control" %}
{% if form.gates %}
@@ -69,8 +69,7 @@
</label>
<div class="col-md-9">
<div class="checkbox">
<label><input type="checkbox" checked="checked"
disabled="disabled"> {% trans "Ask and require input" %}</label>
<label><input type="checkbox" checked="checked" disabled="disabled"> {% trans "Ask and require input" %}</label>
</div>
</div>
</div>
@@ -82,8 +81,7 @@
</label>
<div class="col-md-9 static-form-row">
<p>
<a href="{% url "control:event.settings.invoice" event=request.event.slug organizer=request.organizer.slug %}#tab-0-1-open"
target="_blank">
<a href="{% url "control:event.settings.invoice" event=request.event.slug organizer=request.organizer.slug %}#tab-0-1-open" target="_blank">
{% trans "See invoice settings" %}
</a>
</p>
@@ -103,8 +101,7 @@
</label>
<div class="col-md-9 static-form-row">
<p>
<a href="{% url "control:event.items.questions" event=request.event.slug organizer=request.organizer.slug %}"
target="_blank">
<a href="{% url "control:event.items.questions" event=request.event.slug organizer=request.organizer.slug %}" target="_blank">
{% trans "Manage questions" %}
</a>
</p>
@@ -235,74 +232,10 @@
{% bootstrap_field sform.display_net_prices layout="control" %}
{% bootstrap_field sform.show_variations_expanded layout="control" %}
{% bootstrap_field sform.hide_sold_out layout="control" %}
<div class="form-group">
<label class="col-md-3 control-label">
{% trans "Footer links" %}<br>
<span class="optional">{% trans "Optional" %}</span>
</label>
<div class="col-md-9">
<p class="help-block">
{% blocktrans trimmed %}
These links will be shown in the footer of your ticket shop. You could
for example link your terms of service here. Your contact address, imprint, and privacy
policy will be linked automatically (if you configured them), so you do not need to add
them here.
{% endblocktrans %}
</p>
<div class="formset" data-formset data-formset-prefix="{{ footer_links_formset.prefix }}">
{{ footer_links_formset.management_form }}
{% bootstrap_formset_errors footer_links_formset %}
<div data-formset-body>
{% for form in footer_links_formset %}
<div class="row formset-row" data-formset-form>
<div class="sr-only">
{{ form.id }}
{% bootstrap_field form.DELETE form_group_class="" layout="inline" %}
</div>
<div class="col-md-5">
{% bootstrap_form_errors form %}
{% bootstrap_field form.label layout='inline' form_group_class="" %}
</div>
<div class="col-md-5">
{% bootstrap_field form.url layout='inline' form_group_class="" %}
</div>
<div class="col-md-2 text-right flip">
<button type="button" class="btn btn-danger" data-formset-delete-button>
<i class="fa fa-trash"></i></button>
</div>
</div>
{% endfor %}
</div>
<script type="form-template" data-formset-empty-form>
{% escapescript %}
<div class="row formset-row" data-formset-form>
<div class="sr-only">
{{ footer_links_formset.empty_form.id }}
{% bootstrap_field footer_links_formset.empty_form.DELETE form_group_class="" layout="inline" %}
</div>
<div class="col-md-5">
{% bootstrap_field footer_links_formset.empty_form.label layout='inline' form_group_class="" %}
</div>
<div class="col-md-5">
{% bootstrap_field footer_links_formset.empty_form.url layout='inline' form_group_class="" %}
</div>
<div class="col-md-2 text-right flip">
<button type="button" class="btn btn-danger" data-formset-delete-button>
<i class="fa fa-trash"></i></button>
</div>
</div>
{% endescapescript %}
</script>
<p>
<button type="button" class="btn btn-default" data-formset-add>
<i class="fa fa-plus"></i> {% trans "Add link" %}</button>
</p>
</div>
</div>
</div>
{% url "control:organizer.edit" organizer=request.organizer.slug as org_url %}
{% propagated request.event org_url "meta_noindex" %}
{% bootstrap_field sform.meta_noindex layout="control" %}
{% endpropagated %}
{% if sform.frontpage_subevent_ordering %}
{% bootstrap_field sform.frontpage_subevent_ordering layout="control" %}
{% endif %}
@@ -312,11 +245,6 @@
{% if sform.event_list_available_only %}
{% bootstrap_field sform.event_list_available_only layout="control" %}
{% endif %}
{% url "control:organizer.edit" organizer=request.organizer.slug as org_url %}
{% propagated request.event org_url "meta_noindex" %}
{% bootstrap_field sform.meta_noindex layout="control" %}
{% endpropagated %}
</fieldset>
<fieldset>
<legend>{% trans "Cart" %}</legend>
@@ -334,15 +262,13 @@
</div>
<div class="alert alert-info">
{% blocktrans trimmed %}
The waiting list determines availability mainly based on quotas. If you use a seating plan and
your
The waiting list determines availability mainly based on quotas. If you use a seating plan and your
number of available seats is less than the available quota, you might run into situations where
people are sent an email from the waiting list but still are unable to book a seat.
{% endblocktrans %}
<strong>
{% blocktrans trimmed %}
Specifically, this means the waiting list is not safe to use together with the minimum
distance
Specifically, this means the waiting list is not safe to use together with the minimum distance
feature of our seating plan module.
{% endblocktrans %}
</strong>
@@ -10,7 +10,7 @@
<p>{% blocktrans %}You cannot delete the discount <strong>{{ discount }}</strong> because it already has
been used as part of an order.{% endblocktrans %}</p>
<div class="form-group submit-group">
<a href="{% url "control:event.items.discounts" organizer=request.event.organizer.slug event=request.event.slug %}"
<a href="{% url "control:event.discounts" organizer=request.event.organizer.slug event=request.event.slug %}"
class="btn btn-default btn-cancel">
{% trans "Cancel" %}
</a>
@@ -50,77 +50,6 @@
{% bootstrap_field sform.event_list_availability layout="control" %}
{% bootstrap_field sform.organizer_link_back layout="control" %}
{% bootstrap_field sform.meta_noindex layout="control" %}
<div class="form-group">
<label class="col-md-3 control-label">
{% trans "Footer links" %}<br>
<span class="optional">{% trans "Optional" %}</span>
</label>
<div class="col-md-9">
<p class="help-block">
{% blocktrans trimmed %}
These links will be shown in the footer of your ticket shop. You could
for example link your terms of service here. Your contact address, imprint, and privacy
policy will be linked automatically (if you configured them), so you do not need to add
them here.
{% endblocktrans %}
</p>
<p class="help-block">
{% blocktrans trimmed %}
The links you configure here will also be shown on all of your events.
{% endblocktrans %}
</p>
<div class="formset" data-formset data-formset-prefix="{{ footer_links_formset.prefix }}">
{{ footer_links_formset.management_form }}
{% bootstrap_formset_errors footer_links_formset %}
<div data-formset-body>
{% for form in footer_links_formset %}
<div class="row formset-row" data-formset-form>
<div class="sr-only">
{{ form.id }}
{% bootstrap_field form.DELETE form_group_class="" layout="inline" %}
</div>
<div class="col-md-5">
{% bootstrap_form_errors form %}
{% bootstrap_field form.label layout='inline' form_group_class="" %}
</div>
<div class="col-md-5">
{% bootstrap_field form.url layout='inline' form_group_class="" %}
</div>
<div class="col-md-2 text-right flip">
<button type="button" class="btn btn-danger" data-formset-delete-button>
<i class="fa fa-trash"></i></button>
</div>
</div>
{% endfor %}
</div>
<script type="form-template" data-formset-empty-form>
{% escapescript %}
<div class="row formset-row" data-formset-form>
<div class="sr-only">
{{ footer_links_formset.empty_form.id }}
{% bootstrap_field footer_links_formset.empty_form.DELETE form_group_class="" layout="inline" %}
</div>
<div class="col-md-5">
{% bootstrap_field footer_links_formset.empty_form.label layout='inline' form_group_class="" %}
</div>
<div class="col-md-5">
{% bootstrap_field footer_links_formset.empty_form.url layout='inline' form_group_class="" %}
</div>
<div class="col-md-2 text-right flip">
<button type="button" class="btn btn-danger" data-formset-delete-button>
<i class="fa fa-trash"></i></button>
</div>
</div>
{% endescapescript %}
</script>
<p>
<button type="button" class="btn btn-default" data-formset-add>
<i class="fa fa-plus"></i> {% trans "Add link" %}</button>
</p>
</div>
</div>
</div>
</fieldset>
<fieldset>
<legend>{% trans "Localization" %}</legend>
+6 -21
View File
@@ -74,9 +74,9 @@ from pretix.base.signals import register_ticket_outputs
from pretix.base.templatetags.rich_text import markdown_compile_email
from pretix.control.forms.event import (
CancelSettingsForm, CommentForm, ConfirmTextFormset, EventDeleteForm,
EventFooterLinkFormset, EventMetaValueForm, EventSettingsForm,
EventUpdateForm, InvoiceSettingsForm, ItemMetaPropertyForm,
MailSettingsForm, PaymentSettingsForm, ProviderForm, QuickSetupForm,
EventMetaValueForm, EventSettingsForm, EventUpdateForm,
InvoiceSettingsForm, ItemMetaPropertyForm, MailSettingsForm,
PaymentSettingsForm, ProviderForm, QuickSetupForm,
QuickSetupProductFormSet, TaxRuleForm, TaxRuleLineFormSet,
TicketSettingsForm, WidgetCodeForm,
)
@@ -186,7 +186,6 @@ class EventUpdate(DecoupleMixin, EventSettingsViewMixin, EventPermissionRequired
context['meta_forms'] = self.meta_forms
context['item_meta_property_formset'] = self.item_meta_property_formset
context['confirm_texts_formset'] = self.confirm_texts_formset
context['footer_links_formset'] = self.footer_links_formset
return context
@transaction.atomic
@@ -196,7 +195,6 @@ class EventUpdate(DecoupleMixin, EventSettingsViewMixin, EventPermissionRequired
self.save_meta()
self.save_item_meta_property_formset(self.object)
self.save_confirm_texts_formset(self.object)
self.save_footer_links_formset(self.object)
change_css = False
if self.sform.has_changed() or self.confirm_texts_formset.has_changed():
@@ -206,10 +204,6 @@ class EventUpdate(DecoupleMixin, EventSettingsViewMixin, EventPermissionRequired
self.request.event.log_action('pretix.event.settings', user=self.request.user, data=data)
if any(p in self.sform.changed_data for p in SETTINGS_AFFECTING_CSS):
change_css = True
if self.footer_links_formset.has_changed():
self.request.event.log_action('pretix.event.footerlinks.changed', user=self.request.user, data={
'data': self.footer_links_formset.cleaned_data
})
if form.has_changed():
self.request.event.log_action('pretix.event.changed', user=self.request.user, data={
k: (form.cleaned_data.get(k).name
@@ -244,8 +238,7 @@ class EventUpdate(DecoupleMixin, EventSettingsViewMixin, EventPermissionRequired
def post(self, request, *args, **kwargs):
form = self.get_form()
if form.is_valid() and self.sform.is_valid() and all([f.is_valid() for f in self.meta_forms]) and \
self.item_meta_property_formset.is_valid() and self.confirm_texts_formset.is_valid() and \
self.footer_links_formset.is_valid():
self.item_meta_property_formset.is_valid() and self.confirm_texts_formset.is_valid():
# reset timezone
zone = timezone(self.sform.cleaned_data['timezone'])
event = form.instance
@@ -299,18 +292,10 @@ class EventUpdate(DecoupleMixin, EventSettingsViewMixin, EventPermissionRequired
def save_confirm_texts_formset(self, obj):
obj.settings.confirm_texts = LazyI18nStringList(
form_data['text'].data
for form_data in sorted((d for d in self.confirm_texts_formset.cleaned_data if d), key=operator.itemgetter("ORDER"))
if form_data and not form_data.get("DELETE", False)
for form_data in sorted(self.confirm_texts_formset.cleaned_data, key=operator.itemgetter("ORDER"))
if not form_data.get("DELETE", False)
)
@cached_property
def footer_links_formset(self):
return EventFooterLinkFormset(self.request.POST if self.request.method == "POST" else None, event=self.object,
prefix="footer-links", instance=self.object)
def save_footer_links_formset(self, obj):
self.footer_links_formset.save()
class EventPlugins(EventSettingsViewMixin, EventPermissionRequiredMixin, TemplateView, SingleObjectMixin):
model = Event
+8 -33
View File
@@ -92,8 +92,8 @@ from pretix.control.forms.organizer import (
CustomerCreateForm, CustomerUpdateForm, DeviceBulkEditForm, DeviceForm,
EventMetaPropertyForm, GateForm, GiftCardCreateForm, GiftCardUpdateForm,
MailSettingsForm, MembershipTypeForm, MembershipUpdateForm,
OrganizerDeleteForm, OrganizerFooterLinkFormset, OrganizerForm,
OrganizerSettingsForm, OrganizerUpdateForm, TeamForm, WebHookForm,
OrganizerDeleteForm, OrganizerForm, OrganizerSettingsForm,
OrganizerUpdateForm, TeamForm, WebHookForm,
)
from pretix.control.logdisplay import OVERVIEW_BANLIST
from pretix.control.permissions import (
@@ -416,13 +416,11 @@ class OrganizerUpdate(OrganizerPermissionRequiredMixin, UpdateView):
def get_context_data(self, *args, **kwargs) -> dict:
context = super().get_context_data(*args, **kwargs)
context['sform'] = self.sform
context['footer_links_formset'] = self.footer_links_formset
return context
@transaction.atomic
def form_valid(self, form):
self.sform.save()
self.save_footer_links_formset(self.object)
change_css = False
if self.sform.has_changed():
self.request.organizer.log_action(
@@ -437,10 +435,6 @@ class OrganizerUpdate(OrganizerPermissionRequiredMixin, UpdateView):
)
if any(p in self.sform.changed_data for p in SETTINGS_AFFECTING_CSS):
change_css = True
if self.footer_links_formset.has_changed():
self.request.organizer.log_action('pretix.organizer.footerlinks.changed', user=self.request.user, data={
'data': self.footer_links_formset.cleaned_data
})
if form.has_changed():
self.request.organizer.log_action(
'pretix.organizer.changed',
@@ -472,19 +466,11 @@ class OrganizerUpdate(OrganizerPermissionRequiredMixin, UpdateView):
def post(self, request, *args, **kwargs):
self.object = self.get_object()
form = self.get_form()
if form.is_valid() and self.sform.is_valid() and self.footer_links_formset.is_valid():
if form.is_valid() and self.sform.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form)
@cached_property
def footer_links_formset(self):
return OrganizerFooterLinkFormset(self.request.POST if self.request.method == "POST" else None, organizer=self.object,
prefix="footer-links", instance=self.object)
def save_footer_links_formset(self, obj):
self.footer_links_formset.save()
class OrganizerCreate(CreateView):
model = Organizer
@@ -642,25 +628,14 @@ class TeamDeleteView(OrganizerDetailViewMixin, OrganizerPermissionRequiredMixin,
def delete(self, request, *args, **kwargs):
success_url = self.get_success_url()
self.object = self.get_object()
if not self.is_allowed():
messages.error(request, _('The selected team cannot be deleted.'))
return redirect(success_url)
try:
if self.is_allowed():
self.object.log_action('pretix.team.deleted', user=self.request.user)
self.object.delete()
except ProtectedError:
messages.error(
self.request,
_(
'The team could not be deleted as some constraints (e.g. data created by '
'plug-ins) do not allow it.'
)
)
messages.success(request, _('The selected team has been deleted.'))
return redirect(success_url)
else:
messages.error(request, _('The selected team cannot be deleted.'))
return redirect(success_url)
messages.success(request, _('The selected team has been deleted.'))
return redirect(success_url)
class TeamMemberView(OrganizerDetailViewMixin, OrganizerPermissionRequiredMixin, DetailView):
+7 -18
View File
@@ -25,7 +25,7 @@ from io import BytesIO
from django.core.files.base import ContentFile
from django.core.files.storage import default_storage
from PIL import Image, ImageOps, ImageSequence
from PIL import Image, ImageOps
from PIL.Image import Resampling
from pretix.helpers.models import Thumbnail
@@ -171,23 +171,12 @@ def create_thumbnail(sourcename, size):
except:
raise ThumbnailError('Could not load image')
frames = [resize_image(frame, size) for frame in ImageSequence.Iterator(image)]
image_out = frames[0]
save_kwargs = {}
image = resize_image(image, size)
if source.name.lower().endswith('.jpg') or source.name.lower().endswith('.jpeg'):
# Yields better file sizes for photos
target_ext = 'jpeg'
quality = 95
elif source.name.lower().endswith('.gif') or source.name.lower().endswith('.png'):
target_ext = source.name.lower()[-3:]
quality = None
image_out.info = image.info
save_kwargs = {
'append_images': frames[1:],
'loop': image.info.get('loop', 0),
'save_all': True,
}
else:
target_ext = 'png'
quality = None
@@ -195,11 +184,11 @@ def create_thumbnail(sourcename, size):
checksum = hashlib.md5(image.tobytes()).hexdigest()
name = checksum + '.' + size.replace('^', 'c') + '.' + target_ext
buffer = BytesIO()
if image_out.mode == "P" and source.name.lower().endswith('.png'):
image_out = image_out.convert('RGBA')
if image_out.mode not in ("1", "L", "RGB", "RGBA"):
image_out = image_out.convert('RGB')
image_out.save(fp=buffer, format=target_ext.upper(), quality=quality, **save_kwargs)
if image.mode == "P" and source.name.lower().endswith('.png'):
image = image.convert('RGBA')
if image.mode not in ("1", "L", "RGB", "RGBA"):
image = image.convert('RGB')
image.save(fp=buffer, format=target_ext.upper(), quality=quality)
imgfile = ContentFile(buffer.getvalue())
t = Thumbnail.objects.create(source=sourcename, size=size)
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-07-01 07:50+0000\n"
"POT-Creation-Date: 2022-06-09 15:47+0000\n"
"PO-Revision-Date: 2021-09-15 11:22+0000\n"
"Last-Translator: Mohamed Tawfiq <mtawfiq@wafyapp.com>\n"
"Language-Team: Arabic <https://translate.pretix.eu/projects/pretix/pretix-js/"
@@ -376,7 +376,7 @@ msgstr ""
"نعمل الآن على ارسال طلبك إلى الخادم، إذا أستغرقت العملية أكثر من دقيقة، يرجى "
"التحقق من اتصالك بالإنترنت ثم أعد تحميل الصفحة مرة أخرى."
#: pretix/static/pretixbase/js/asynctask.js:276
#: pretix/static/pretixbase/js/asynctask.js:273
#: pretix/static/pretixcontrol/js/ui/main.js:71
msgid "Close message"
msgstr "أغلق الرسالة"
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-07-01 07:50+0000\n"
"POT-Creation-Date: 2022-06-09 15:47+0000\n"
"PO-Revision-Date: 2020-12-19 07:00+0000\n"
"Last-Translator: albert <albert.serra.monner@gmail.com>\n"
"Language-Team: Catalan <https://translate.pretix.eu/projects/pretix/pretix-"
@@ -359,7 +359,7 @@ msgid ""
"page and try again."
msgstr ""
#: pretix/static/pretixbase/js/asynctask.js:276
#: pretix/static/pretixbase/js/asynctask.js:273
#: pretix/static/pretixcontrol/js/ui/main.js:71
msgid "Close message"
msgstr ""
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-07-01 07:50+0000\n"
"POT-Creation-Date: 2022-06-09 15:47+0000\n"
"PO-Revision-Date: 2021-12-06 23:00+0000\n"
"Last-Translator: Ondřej Sokol <osokol@treesoft.cz>\n"
"Language-Team: Czech <https://translate.pretix.eu/projects/pretix/pretix-js/"
@@ -373,7 +373,7 @@ msgstr ""
"prosím zkontrolujte své internetové připojení a znovu načtěte stránku a "
"zkuste to znovu."
#: pretix/static/pretixbase/js/asynctask.js:276
#: pretix/static/pretixbase/js/asynctask.js:273
#: pretix/static/pretixcontrol/js/ui/main.js:71
msgid "Close message"
msgstr "Zavřít zprávu"
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-07-01 07:50+0000\n"
"POT-Creation-Date: 2022-06-09 15:47+0000\n"
"PO-Revision-Date: 2022-04-01 13:36+0000\n"
"Last-Translator: Anna-itk <abc@aarhus.dk>\n"
"Language-Team: Danish <https://translate.pretix.eu/projects/pretix/pretix-js/"
@@ -398,7 +398,7 @@ msgstr ""
"Din forespørgsel bliver sendt til serveren. Hvis det tager mere end et "
"minut, så tjek din internetforbindelse, genindlæs siden og prøv igen."
#: pretix/static/pretixbase/js/asynctask.js:276
#: pretix/static/pretixbase/js/asynctask.js:273
#: pretix/static/pretixcontrol/js/ui/main.js:71
msgid "Close message"
msgstr "Luk besked"
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-07-01 07:50+0000\n"
"POT-Creation-Date: 2022-06-09 15:47+0000\n"
"PO-Revision-Date: 2022-04-28 18:04+0000\n"
"Last-Translator: Raphael Michel <michel@rami.io>\n"
"Language-Team: German <https://translate.pretix.eu/projects/pretix/pretix-js/"
@@ -374,7 +374,7 @@ msgstr ""
"dauert, prüfen Sie bitte Ihre Internetverbindung. Danach können Sie diese "
"Seite neu laden und es erneut versuchen."
#: pretix/static/pretixbase/js/asynctask.js:276
#: pretix/static/pretixbase/js/asynctask.js:273
#: pretix/static/pretixcontrol/js/ui/main.js:71
msgid "Close message"
msgstr "Schließen"
-1
View File
@@ -153,7 +153,6 @@ Kosovo
landesspezifische
Lead
Leaflet
Linktext
loszulegen
Ltd
max
File diff suppressed because it is too large Load Diff
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-07-01 07:50+0000\n"
"POT-Creation-Date: 2022-06-09 15:47+0000\n"
"PO-Revision-Date: 2022-04-28 18:04+0000\n"
"Last-Translator: Raphael Michel <michel@rami.io>\n"
"Language-Team: German (informal) <https://translate.pretix.eu/projects/"
@@ -373,7 +373,7 @@ msgstr ""
"dauert, prüfe bitte deine Internetverbindung. Danach kannst du diese Seite "
"neu laden und es erneut versuchen."
#: pretix/static/pretixbase/js/asynctask.js:276
#: pretix/static/pretixbase/js/asynctask.js:273
#: pretix/static/pretixcontrol/js/ui/main.js:71
msgid "Close message"
msgstr "Schließen"
@@ -153,7 +153,6 @@ Kosovo
landesspezifische
Lead
Leaflet
Linktext
loszulegen
Ltd
max
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-07-01 07:50+0000\n"
"POT-Creation-Date: 2022-06-09 15:47+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -358,7 +358,7 @@ msgid ""
"page and try again."
msgstr ""
#: pretix/static/pretixbase/js/asynctask.js:276
#: pretix/static/pretixbase/js/asynctask.js:273
#: pretix/static/pretixcontrol/js/ui/main.js:71
msgid "Close message"
msgstr ""
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-07-01 07:50+0000\n"
"POT-Creation-Date: 2022-06-09 15:47+0000\n"
"PO-Revision-Date: 2019-10-03 19:00+0000\n"
"Last-Translator: Chris Spy <chrispiropoulou@hotmail.com>\n"
"Language-Team: Greek <https://translate.pretix.eu/projects/pretix/pretix-js/"
@@ -405,7 +405,7 @@ msgstr ""
"περισσότερο από ένα λεπτό, ελέγξτε τη σύνδεσή σας στο διαδίκτυο και στη "
"συνέχεια επαναλάβετε τη φόρτωση αυτής της σελίδας και δοκιμάστε ξανά."
#: pretix/static/pretixbase/js/asynctask.js:276
#: pretix/static/pretixbase/js/asynctask.js:273
#: pretix/static/pretixcontrol/js/ui/main.js:71
msgid "Close message"
msgstr "Κλείσιμο μηνύματος"
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-07-01 07:50+0000\n"
"POT-Creation-Date: 2022-06-09 15:47+0000\n"
"PO-Revision-Date: 2021-11-25 21:00+0000\n"
"Last-Translator: Ismael Menéndez Fernández <ismael.menendez@balidea.com>\n"
"Language-Team: Spanish <https://translate.pretix.eu/projects/pretix/pretix-"
@@ -373,7 +373,7 @@ msgstr ""
"minuto, por favor, revise su conexión a Internet, recargue la página e "
"intente nuevamente."
#: pretix/static/pretixbase/js/asynctask.js:276
#: pretix/static/pretixbase/js/asynctask.js:273
#: pretix/static/pretixcontrol/js/ui/main.js:71
msgid "Close message"
msgstr "Cerrar mensaje"
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-07-01 07:50+0000\n"
"POT-Creation-Date: 2022-06-09 15:47+0000\n"
"PO-Revision-Date: 2021-11-10 05:00+0000\n"
"Last-Translator: Jaakko Rinta-Filppula <jaakko@r-f.fi>\n"
"Language-Team: Finnish <https://translate.pretix.eu/projects/pretix/pretix-"
@@ -375,7 +375,7 @@ msgid ""
"page and try again."
msgstr ""
#: pretix/static/pretixbase/js/asynctask.js:276
#: pretix/static/pretixbase/js/asynctask.js:273
#: pretix/static/pretixcontrol/js/ui/main.js:71
msgid "Close message"
msgstr "Sulje viesti"
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: French\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-07-01 07:50+0000\n"
"POT-Creation-Date: 2022-06-09 15:47+0000\n"
"PO-Revision-Date: 2022-04-07 10:40+0000\n"
"Last-Translator: Eva-Maria Obermann <obermann@rami.io>\n"
"Language-Team: French <https://translate.pretix.eu/projects/pretix/pretix-js/"
@@ -398,7 +398,7 @@ msgstr ""
"d'une minute, veuillez vérifier votre connexion Internet, puis recharger "
"cette page et réessayer."
#: pretix/static/pretixbase/js/asynctask.js:276
#: pretix/static/pretixbase/js/asynctask.js:273
#: pretix/static/pretixcontrol/js/ui/main.js:71
msgid "Close message"
msgstr "Fermer le message"
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-07-01 07:50+0000\n"
"POT-Creation-Date: 2022-06-09 15:47+0000\n"
"PO-Revision-Date: 2022-02-22 22:00+0000\n"
"Last-Translator: Ismael Menéndez Fernández <ismael.menendez@balidea.com>\n"
"Language-Team: Galician <https://translate.pretix.eu/projects/pretix/pretix-"
@@ -373,7 +373,7 @@ msgstr ""
"dun minuto, por favor, revise a súa conexión a Internet, recargue a páxina e "
"inténteo de novo."
#: pretix/static/pretixbase/js/asynctask.js:276
#: pretix/static/pretixbase/js/asynctask.js:273
#: pretix/static/pretixcontrol/js/ui/main.js:71
msgid "Close message"
msgstr "Cerrar mensaxe"
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-07-01 07:50+0000\n"
"POT-Creation-Date: 2022-06-09 15:47+0000\n"
"PO-Revision-Date: 2021-09-24 13:54+0000\n"
"Last-Translator: ofirtro <ofir.tro@gmail.com>\n"
"Language-Team: Hebrew <https://translate.pretix.eu/projects/pretix/pretix-js/"
@@ -362,7 +362,7 @@ msgid ""
"page and try again."
msgstr ""
#: pretix/static/pretixbase/js/asynctask.js:276
#: pretix/static/pretixbase/js/asynctask.js:273
#: pretix/static/pretixcontrol/js/ui/main.js:71
msgid "Close message"
msgstr ""
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-07-01 07:50+0000\n"
"POT-Creation-Date: 2022-06-09 15:47+0000\n"
"PO-Revision-Date: 2020-01-24 08:00+0000\n"
"Last-Translator: Prokaj Miklós <mixolid0@gmail.com>\n"
"Language-Team: Hungarian <https://translate.pretix.eu/projects/pretix/pretix-"
@@ -398,7 +398,7 @@ msgstr ""
"hosszabb időt vesz igénybe, kérjük ellenőrizze az internetkapcsolatát, "
"frissítse az oldalt és próbálkozzon újra."
#: pretix/static/pretixbase/js/asynctask.js:276
#: pretix/static/pretixbase/js/asynctask.js:273
#: pretix/static/pretixcontrol/js/ui/main.js:71
msgid "Close message"
msgstr "Üzenet bezárása"
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-07-01 07:50+0000\n"
"POT-Creation-Date: 2022-06-09 15:47+0000\n"
"PO-Revision-Date: 2022-05-08 19:00+0000\n"
"Last-Translator: Emanuele Signoretta <signorettae@gmail.com>\n"
"Language-Team: Italian <https://translate.pretix.eu/projects/pretix/pretix-"
@@ -375,7 +375,7 @@ msgstr ""
"più di un minuto si prega di verificare la connessione internet e ricaricare "
"la pagina per riprovare l'invio."
#: pretix/static/pretixbase/js/asynctask.js:276
#: pretix/static/pretixbase/js/asynctask.js:273
#: pretix/static/pretixcontrol/js/ui/main.js:71
msgid "Close message"
msgstr "Messaggio di chiusura"
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-07-01 07:50+0000\n"
"POT-Creation-Date: 2022-06-09 15:47+0000\n"
"PO-Revision-Date: 2022-03-15 00:00+0000\n"
"Last-Translator: Yuriko Matsunami <y.matsunami@enobyte.com>\n"
"Language-Team: Japanese <https://translate.pretix.eu/projects/pretix/pretix-"
@@ -372,7 +372,7 @@ msgstr ""
"ターネット接続を確認してください。確認完了後、ウェブページを再度読込み、再試"
"行してください。"
#: pretix/static/pretixbase/js/asynctask.js:276
#: pretix/static/pretixbase/js/asynctask.js:273
#: pretix/static/pretixcontrol/js/ui/main.js:71
msgid "Close message"
msgstr "閉じる"
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-07-01 07:50+0000\n"
"POT-Creation-Date: 2022-06-09 15:47+0000\n"
"PO-Revision-Date: 2022-04-06 03:00+0000\n"
"Last-Translator: Liga V <lerning_by_dreaming@gmx.de>\n"
"Language-Team: Latvian <https://translate.pretix.eu/projects/pretix/pretix-"
@@ -374,7 +374,7 @@ msgstr ""
"aizņem ilgāk kā vienu minūti, lūdzu, pārbaudiet savu interneta savienojumu, "
"pārlādējiet šo lapu un mēģiniet vēlreiz."
#: pretix/static/pretixbase/js/asynctask.js:276
#: pretix/static/pretixbase/js/asynctask.js:273
#: pretix/static/pretixcontrol/js/ui/main.js:71
msgid "Close message"
msgstr "Aizvērt ziņu"
File diff suppressed because it is too large Load Diff
+151 -156
View File
@@ -7,9 +7,9 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-07-01 07:50+0000\n"
"PO-Revision-Date: 2022-06-20 02:00+0000\n"
"Last-Translator: fyksen <fredrik@fyksen.me>\n"
"POT-Creation-Date: 2022-06-09 15:47+0000\n"
"PO-Revision-Date: 2021-05-31 11:26+0000\n"
"Last-Translator: zackern <zacker@zacker.no>\n"
"Language-Team: Norwegian Bokmål <https://translate.pretix.eu/projects/pretix/"
"pretix-js/nb_NO/>\n"
"Language: nb_NO\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.12.2\n"
"X-Generator: Weblate 4.6\n"
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
@@ -31,103 +31,103 @@ msgstr "Kommentar:"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:34
msgid "PayPal"
msgstr "PayPal"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:35
msgid "Venmo"
msgstr "Venmo"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:36
msgid "Apple Pay"
msgstr "Apple Pay"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:37
msgid "Itaú"
msgstr "Itaú"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:38
msgid "PayPal Credit"
msgstr "PayPal Credit"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:39
msgid "Credit Card"
msgstr "Kredittkort"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:40
msgid "PayPal Pay Later"
msgstr "PayPal Pay Later"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:41
msgid "iDEAL"
msgstr "iDEAL"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:42
msgid "SEPA Direct Debit"
msgstr "SEPA Direct Debit"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:43
msgid "Bancontact"
msgstr "Bancontact"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:44
msgid "giropay"
msgstr "giropay"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:45
msgid "SOFORT"
msgstr "SOFORT"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:46
msgid "eps"
msgstr "eps"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:47
msgid "MyBank"
msgstr "MyBank"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:48
msgid "Przelewy24"
msgstr "Przelewy24"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:49
msgid "Verkkopankki"
msgstr "Verkkopankki"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:50
msgid "PayU"
msgstr "PayU"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:51
msgid "BLIK"
msgstr "BLIK"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:52
msgid "Trustly"
msgstr "Trustly"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:53
msgid "Zimpler"
msgstr "Zimpler"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:54
msgid "Maxima"
msgstr "Maxima"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:55
msgid "OXXO"
msgstr "OXXO"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:56
msgid "Boleto"
msgstr "Boleto"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:57
msgid "WeChat Pay"
msgstr "WeChat Pay"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:58
msgid "Mercado Pago"
msgstr "Mercado Pago"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:157
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:48
@@ -142,7 +142,7 @@ msgstr "Bekrefter betalingen din…"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:240
msgid "Payment method unavailable"
msgstr "Betalingsmetode ikke tilgjengelig"
msgstr ""
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:15
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:39
@@ -176,7 +176,7 @@ msgstr "Velg en innsjekkingsliste"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:31
msgid "No active check-in lists found."
msgstr "Ingen aktive innsjekkingslister funnet."
msgstr "Ingen aktive innsjekkingslister"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:32
msgid "Switch check-in list"
@@ -270,11 +270,13 @@ msgstr "Informasjon trengs"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:56
msgid "Unknown ticket"
msgstr "Ukjent billett"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:57
#, fuzzy
#| msgid "Entry not allowed"
msgid "Ticket type not allowed here"
msgstr "Denne Billettypen er ikke lov ikke her"
msgstr "Inngang ikke tillatt"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:59
msgid "Entry not allowed"
@@ -282,7 +284,7 @@ msgstr "Inngang ikke tillatt"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:60
msgid "Ticket code revoked/changed"
msgstr "Billettkode tilbakekalt/endret"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:61
msgid "Order canceled"
@@ -302,7 +304,7 @@ msgstr "Inne nå"
#: pretix/static/lightbox/js/lightbox.js:96
msgid "close"
msgstr "lukk"
msgstr ""
#: pretix/static/pretixbase/js/asynctask.js:43
#: pretix/static/pretixbase/js/asynctask.js:120
@@ -310,8 +312,6 @@ msgid ""
"Your request is currently being processed. Depending on the size of your "
"event, this might take up to a few minutes."
msgstr ""
"Din forespørsel blir prosessert. Dette kan ta minutter, men varierer ut fra "
"hvor stort arrangementet er."
#: pretix/static/pretixbase/js/asynctask.js:48
#: pretix/static/pretixbase/js/asynctask.js:125
@@ -334,7 +334,7 @@ msgstr ""
#: pretix/static/pretixbase/js/asynctask.js:183
#: pretix/static/pretixcontrol/js/ui/mail.js:24
msgid "An error of type {code} occurred."
msgstr "En feil av type {code} oppsto."
msgstr "En feil oppsto: {code}"
#: pretix/static/pretixbase/js/asynctask.js:93
msgid ""
@@ -366,10 +366,8 @@ msgid ""
"than one minute, please check your internet connection and then reload this "
"page and try again."
msgstr ""
"Vi sender forespørslene dine til serveren. Hvis dette tar langre tid en ett "
"minutt, sjekk internett koblingen din og deretter last siden og prøv på nytt."
#: pretix/static/pretixbase/js/asynctask.js:276
#: pretix/static/pretixbase/js/asynctask.js:273
#: pretix/static/pretixcontrol/js/ui/main.js:71
msgid "Close message"
msgstr "Lukk melding"
@@ -409,322 +407,323 @@ msgstr "Nåværende dato og tid"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:71
msgid "Current day of the week (1 = Monday, 7 = Sunday)"
msgstr "Gjeldene ukedag (1 = Mandag, 7 = Søndag)"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:75
#, fuzzy
msgid "Number of previous entries"
msgstr "Antall tidligere oppføringer"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:79
#, fuzzy
msgid "Number of previous entries since midnight"
msgstr "Antall tidligere oppføringer siden midnatt"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:83
#, fuzzy
msgid "Number of days with a previous entry"
msgstr "Antall dager med en tidligere oppføring"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:87
msgid "Minutes since last entry (-1 on first entry)"
msgstr "Minutter siden siste oppføring (-1 på første oppføring)"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:91
msgid "Minutes since first entry (-1 on first entry)"
msgstr "Minutter siden første oppføring (-1 på første oppføring)"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:112
msgid "All of the conditions below (AND)"
msgstr "Alle betingelsene nedenfor (AND)"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:113
msgid "At least one of the conditions below (OR)"
msgstr "Minst en av betingelsene nedenfor (OR)"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:114
msgid "Event start"
msgstr "Event start"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:115
msgid "Event end"
msgstr "Event slutt"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:116
msgid "Event admission"
msgstr "Event inngang"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:117
msgid "custom date and time"
msgstr "egendefinert dato og klokkeslett"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:118
msgid "custom time"
msgstr "egendefinert tid"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:119
msgid "Tolerance (minutes)"
msgstr "Toleranse (minutter)"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:120
msgid "Add condition"
msgstr "Legg til betingelse"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:121
msgid "minutes"
msgstr "minutter"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:71
msgid "Check-in QR"
msgstr "Sjekk-in QR"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:382
msgid "The PDF background file could not be loaded for the following reason:"
msgstr "PDF bakgrunnsfilen kunne ikke lastes av følgende årsak:"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:630
msgid "Group of objects"
msgstr "Gruppe med objekter"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:636
msgid "Text object"
msgstr "Tekst objekt"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:638
msgid "Barcode area"
msgstr "Strekkodeområde"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:640
msgid "Image area"
msgstr "Bildeområde"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:642
msgid "Powered by pretix"
msgstr "Drevet av pretix"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:644
msgid "Object"
msgstr "Objekt"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:648
msgid "Ticket design"
msgstr "Billett design"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:938
msgid "Saving failed."
msgstr "Lagring feilet."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:988
#: pretix/static/pretixcontrol/js/ui/editor.js:1027
msgid "Error while uploading your PDF file, please try again."
msgstr "Feil ved opplasting av PDF fil, prøv på nytt."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:1012
msgid "Do you really want to leave the editor without saving your changes?"
msgstr "Vil du avslutte editoren uten å lagre endringene?"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/mail.js:19
msgid "An error has occurred."
msgstr "En feil har oppstått."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/mail.js:54
msgid "Generating messages …"
msgstr "Genererer meldinger…"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:107
msgid "Unknown error."
msgstr "Ukjent feil."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:308
msgid "Your color has great contrast and is very easy to read!"
msgstr "Fargen du valgte har høy kontrast og er veldig enkel å lese!"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:312
msgid "Your color has decent contrast and is probably good-enough to read!"
msgstr "Fargen du valgte har grei kontrast og er ganske enkel å lese!"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:316
msgid ""
"Your color has bad contrast for text on white background, please choose a "
"darker shade."
msgstr "Fargen du valgte har dårlig kontrast mot hvit, velg en mørkere farge."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:454
msgid "All"
msgstr "Alle"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:455
msgid "None"
msgstr "Ingen"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:456
msgid "Search query"
msgstr "Søkeord"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:459
msgid "Selected only"
msgstr "Kun valgte"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:886
msgid "Use a different name internally"
msgstr "Bruk et annet navn internt"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:922
msgid "Click to close"
msgstr "Klikk for å lukke"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:963
msgid "You have unsaved changes!"
msgstr "Du har ikke-lagrede endringer!"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/orderchange.js:25
msgid "Calculating default price…"
msgstr "Regner ut standardpris…"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/question.js:42
msgid "Others"
msgstr "Andre"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/question.js:82
msgid "Count"
msgstr "Tell"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/question.js:136
#: pretix/static/pretixpresale/js/ui/questions.js:269
msgid "Yes"
msgstr "Ja"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/question.js:137
#: pretix/static/pretixpresale/js/ui/questions.js:269
msgid "No"
msgstr "Nei"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/subevent.js:111
msgid "(one more date)"
msgid_plural "({num} more dates)"
msgstr[0] "(en mer dato)"
msgstr[1] "({num} flere datoer)"
msgstr[0] ""
msgstr[1] ""
#: pretix/static/pretixpresale/js/ui/cart.js:43
msgid ""
"The items in your cart are no longer reserved for you. You can still "
"complete your order as long as theyre available."
msgstr ""
"Varene i handlekurven din er ikke lenger reservert for deg. Du kan fortsatt "
"fullføre bestillingen din så lenge de er tilgjengelige."
#: pretix/static/pretixpresale/js/ui/cart.js:45
msgid "Cart expired"
msgstr "Handlevognen har utløpt"
msgstr ""
#: pretix/static/pretixpresale/js/ui/cart.js:50
msgid "The items in your cart are reserved for you for one minute."
msgid_plural "The items in your cart are reserved for you for {num} minutes."
msgstr[0] "Varene i handlekurven din er reservert for deg i ett minutt."
msgstr[1] "Varene i handlekurven din er reservert for deg i {num} minutter."
msgstr[0] ""
msgstr[1] ""
#: pretix/static/pretixpresale/js/ui/main.js:144
msgid "The organizer keeps %(currency)s %(amount)s"
msgstr "Arrangøren beholder %(currency)s %(beløp)"
msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:152
msgid "You get %(currency)s %(amount)s back"
msgstr "Du mottar %(currency)s %(amount)s tilbake"
msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:168
msgid "Please enter the amount the organizer can keep."
msgstr "Vennligst skriv inn beløpet arrangøren kan beholde."
msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:377
msgid "Please enter a quantity for one of the ticket types."
msgstr "Vennligst skriv inn et antall for en av billetttypene."
msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:413
msgid "required"
msgstr "nødvendig"
msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:516
#: pretix/static/pretixpresale/js/ui/main.js:535
msgid "Time zone:"
msgstr "Tidssone:"
msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:526
msgid "Your local time:"
msgstr "Din lokale tid:"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:17
msgctxt "widget"
msgid "Sold out"
msgstr "Utsolgt"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:18
msgctxt "widget"
msgid "Buy"
msgstr "Kjøp"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:19
msgctxt "widget"
msgid "Register"
msgstr "Registrer"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:20
msgctxt "widget"
msgid "Reserved"
msgstr "Reservert"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:21
msgctxt "widget"
msgid "FREE"
msgstr "GRATIS"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:22
msgctxt "widget"
msgid "from %(currency)s %(price)s"
msgstr "fra %(currency)s %(price)s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:23
msgctxt "widget"
msgid "incl. %(rate)s% %(taxname)s"
msgstr "inkl. %(rate)s% %(taxname)s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:24
msgctxt "widget"
msgid "plus %(rate)s% %(taxname)s"
msgstr "pluss %(rate)s% %(taxname)s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:25
msgctxt "widget"
msgid "incl. taxes"
msgstr "Inkl. skatt"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:26
msgctxt "widget"
msgid "plus taxes"
msgstr "pluss skatt"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:27
#, javascript-format
msgctxt "widget"
msgid "currently available: %s"
msgstr "tilgjengelig for øyeblikket: %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:28
msgctxt "widget"
msgid "Only available with a voucher"
msgstr "Kun tilgjengelig med kupong"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:29
#, javascript-format
msgctxt "widget"
msgid "minimum amount to order: %s"
msgstr "minimumsbeløp for bestilling: %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:30
msgctxt "widget"
msgid "Close ticket shop"
msgstr "Steng billettbutikken"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:31
msgctxt "widget"
msgid "The ticket shop could not be loaded."
msgstr "Billettbutikken kunne ikke lastes."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:32
msgctxt "widget"
@@ -732,18 +731,16 @@ msgid ""
"There are currently a lot of users in this ticket shop. Please open the shop "
"in a new tab to continue."
msgstr ""
"Det er for tiden mange brukere i denne billettbutikken. Åpne butikken i en "
"ny fane for å fortsette."
#: pretix/static/pretixpresale/js/widget/widget.js:34
msgctxt "widget"
msgid "Open ticket shop"
msgstr "Åpne billettbutikk"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:35
msgctxt "widget"
msgid "The cart could not be created. Please try again later"
msgstr "Handlekurven kunne ikke opprettes. Vennligst prøv igjen senere"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:36
msgctxt "widget"
@@ -751,13 +748,11 @@ msgid ""
"We could not create your cart, since there are currently too many users in "
"this ticket shop. Please click \"Continue\" to retry in a new tab."
msgstr ""
"Vi kunne ikke opprette din handlekurv, på grunn av for mange brukere i "
"billettshopen. Vennligst klikk «Fortsett» for å prøve på nytt i en ny fane."
#: pretix/static/pretixpresale/js/widget/widget.js:38
msgctxt "widget"
msgid "Waiting list"
msgstr "Venteliste"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:39
msgctxt "widget"
@@ -765,164 +760,164 @@ msgid ""
"You currently have an active cart for this event. If you select more "
"products, they will be added to your existing cart."
msgstr ""
"Du har allerede en aktiv handlekurv for dette arrangementet. Hvis du velger "
"flere produkter, vil disse bli lagt til i den eksisterende handlekurven."
#: pretix/static/pretixpresale/js/widget/widget.js:41
msgctxt "widget"
msgid "Resume checkout"
msgstr "Gjenoppta kassen"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:42
msgctxt "widget"
msgid "Redeem a voucher"
msgstr "Løs inn en kupong"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:43
msgctxt "widget"
msgid "Redeem"
msgstr "Løs inn"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:44
msgctxt "widget"
msgid "Voucher code"
msgstr "Kupongkode"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:45
msgctxt "widget"
msgid "Close"
msgstr "Lukk"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:46
msgctxt "widget"
msgid "Continue"
msgstr "Fortsett"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:47
msgctxt "widget"
msgid "See variations"
msgstr "Se variasjoner"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:48
msgctxt "widget"
msgid "Choose a different event"
msgstr "Velg et annet arrangement"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:49
msgctxt "widget"
msgid "Choose a different date"
msgstr "Velg en annen dato"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:50
msgctxt "widget"
msgid "Back"
msgstr "Tilbake"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:51
msgctxt "widget"
msgid "Next month"
msgstr "Neste måned"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:52
msgctxt "widget"
msgid "Previous month"
msgstr "Forrige måned"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:53
msgctxt "widget"
msgid "Next week"
msgstr "Neste uke"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:54
msgctxt "widget"
msgid "Previous week"
msgstr "Forrige uke"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:55
msgctxt "widget"
msgid "Open seat selection"
msgstr "Åpne setevalg"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:56
#, fuzzy
#| msgid "Load more"
msgctxt "widget"
msgid "Load more"
msgstr "Last mer"
#: pretix/static/pretixpresale/js/widget/widget.js:58
msgid "Mo"
msgstr "Ma"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:59
msgid "Tu"
msgstr "Ti"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:60
msgid "We"
msgstr "On"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:61
msgid "Th"
msgstr "To"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:62
msgid "Fr"
msgstr "Fr"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:63
msgid "Sa"
msgstr ""
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:64
msgid "Su"
msgstr ""
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:67
msgid "January"
msgstr "Januar"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:68
msgid "February"
msgstr "Februar"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:69
msgid "March"
msgstr "Mars"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:70
msgid "April"
msgstr "April"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:71
msgid "May"
msgstr "Mai"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:72
msgid "June"
msgstr "Juni"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:73
msgid "July"
msgstr "Juli"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:74
msgid "August"
msgstr "August"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:75
msgid "September"
msgstr "September"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:76
msgid "October"
msgstr "Oktober"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:77
msgid "November"
msgstr "November"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:78
msgid "December"
msgstr "Desember"
msgstr ""
#~ msgid "Invalid product"
#~ msgstr "Ugyldig produkt"
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-07-01 07:50+0000\n"
"POT-Creation-Date: 2022-06-09 15:47+0000\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/"
@@ -371,7 +371,7 @@ msgstr ""
"Uw aanvraag wordt naar de server verstuurd. Controleer uw internetverbinding "
"en probeer het opnieuw als dit langer dan een minuut duurt."
#: pretix/static/pretixbase/js/asynctask.js:276
#: pretix/static/pretixbase/js/asynctask.js:273
#: pretix/static/pretixcontrol/js/ui/main.js:71
msgid "Close message"
msgstr "Sluit bericht"
File diff suppressed because it is too large Load Diff
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-07-01 07:50+0000\n"
"POT-Creation-Date: 2022-06-09 15:47+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
@@ -357,7 +357,7 @@ msgid ""
"page and try again."
msgstr ""
#: pretix/static/pretixbase/js/asynctask.js:276
#: pretix/static/pretixbase/js/asynctask.js:273
#: pretix/static/pretixcontrol/js/ui/main.js:71
msgid "Close message"
msgstr ""
File diff suppressed because it is too large Load Diff
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-07-01 07:50+0000\n"
"POT-Creation-Date: 2022-06-09 15:47+0000\n"
"PO-Revision-Date: 2021-08-05 04:00+0000\n"
"Last-Translator: Maarten van den Berg <maartenberg1@gmail.com>\n"
"Language-Team: Dutch (informal) <https://translate.pretix.eu/projects/pretix/"
@@ -375,7 +375,7 @@ msgstr ""
"Je aanvraag wordt naar de server verstuurd. Controleer je internetverbinding "
"en probeer het opnieuw als dit langer dan een minuut duurt."
#: pretix/static/pretixbase/js/asynctask.js:276
#: pretix/static/pretixbase/js/asynctask.js:273
#: pretix/static/pretixcontrol/js/ui/main.js:71
msgid "Close message"
msgstr "Sluit bericht"
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-07-01 07:50+0000\n"
"POT-Creation-Date: 2022-06-09 15:47+0000\n"
"PO-Revision-Date: 2019-09-24 19:00+0000\n"
"Last-Translator: Serge Bazanski <q3k@hackerspace.pl>\n"
"Language-Team: Polish <https://translate.pretix.eu/projects/pretix/pretix-js/"
@@ -403,7 +403,7 @@ msgstr ""
"dłuższego niż minuta prosimy o sprawdzenie łączności z Internetem a "
"następnie o przeładowanie strony i ponowienie próby."
#: pretix/static/pretixbase/js/asynctask.js:276
#: pretix/static/pretixbase/js/asynctask.js:273
#: pretix/static/pretixcontrol/js/ui/main.js:71
msgid "Close message"
msgstr "Zamknięcie wiadomości"
File diff suppressed because it is too large Load Diff
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-07-01 07:50+0000\n"
"POT-Creation-Date: 2022-06-09 15:47+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
@@ -358,7 +358,7 @@ msgid ""
"page and try again."
msgstr ""
#: pretix/static/pretixbase/js/asynctask.js:276
#: pretix/static/pretixbase/js/asynctask.js:273
#: pretix/static/pretixcontrol/js/ui/main.js:71
msgid "Close message"
msgstr ""
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-07-01 07:50+0000\n"
"POT-Creation-Date: 2022-06-09 15:47+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -358,7 +358,7 @@ msgid ""
"page and try again."
msgstr ""
#: pretix/static/pretixbase/js/asynctask.js:276
#: pretix/static/pretixbase/js/asynctask.js:273
#: pretix/static/pretixcontrol/js/ui/main.js:71
msgid "Close message"
msgstr ""
File diff suppressed because it is too large Load Diff
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-07-01 07:50+0000\n"
"POT-Creation-Date: 2022-06-09 15:47+0000\n"
"PO-Revision-Date: 2019-03-19 09:00+0000\n"
"Last-Translator: Vitor Reis <vitor.reis7@gmail.com>\n"
"Language-Team: Portuguese (Brazil) <https://translate.pretix.eu/projects/"
@@ -406,7 +406,7 @@ msgstr ""
"minuto, verifique sua conexão com a internet e, em seguida, recarregue esta "
"página e tente novamente."
#: pretix/static/pretixbase/js/asynctask.js:276
#: pretix/static/pretixbase/js/asynctask.js:273
#: pretix/static/pretixcontrol/js/ui/main.js:71
msgid "Close message"
msgstr "Fechar mensagem"
File diff suppressed because it is too large Load Diff
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-07-01 07:50+0000\n"
"POT-Creation-Date: 2022-06-09 15:47+0000\n"
"PO-Revision-Date: 2020-10-27 06:00+0000\n"
"Last-Translator: David Vaz <davidmgvaz@gmail.com>\n"
"Language-Team: Portuguese (Portugal) <https://translate.pretix.eu/projects/"
@@ -389,7 +389,7 @@ msgstr ""
"de um minuto, verifique a sua ligação à Internet e, em seguida, recarregue "
"esta página e tente novamente."
#: pretix/static/pretixbase/js/asynctask.js:276
#: pretix/static/pretixbase/js/asynctask.js:273
#: pretix/static/pretixcontrol/js/ui/main.js:71
msgid "Close message"
msgstr "Fechar mensagem"
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-07-01 07:50+0000\n"
"POT-Creation-Date: 2022-06-09 15:47+0000\n"
"PO-Revision-Date: 2022-04-29 04:00+0000\n"
"Last-Translator: Edd28 <chitu_edy@yahoo.com>\n"
"Language-Team: Romanian <https://translate.pretix.eu/projects/pretix/pretix-"
@@ -373,7 +373,7 @@ msgstr ""
"un minut, te rugăm să verifici conexiunea la internet, să reîncarci această "
"pagină și să reîncerci."
#: pretix/static/pretixbase/js/asynctask.js:276
#: pretix/static/pretixbase/js/asynctask.js:273
#: pretix/static/pretixcontrol/js/ui/main.js:71
msgid "Close message"
msgstr "Închide mesajul"
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-07-01 07:50+0000\n"
"POT-Creation-Date: 2022-06-09 15:47+0000\n"
"PO-Revision-Date: 2021-08-09 13:10+0000\n"
"Last-Translator: Svyatoslav <slava@digitalarthouse.eu>\n"
"Language-Team: Russian <https://translate.pretix.eu/projects/pretix/pretix-"
@@ -401,7 +401,7 @@ msgstr ""
"Отправляем ваш запрос на сервер. Если это займёт больше минуты, проверьте "
"подключение к интернету, затем перезагрузите страницу и повторите попытку."
#: pretix/static/pretixbase/js/asynctask.js:276
#: pretix/static/pretixbase/js/asynctask.js:273
#: pretix/static/pretixcontrol/js/ui/main.js:71
msgid "Close message"
msgstr "Закрыть сообщение"
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-07-01 07:50+0000\n"
"POT-Creation-Date: 2022-06-09 15:47+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
@@ -357,7 +357,7 @@ msgid ""
"page and try again."
msgstr ""
#: pretix/static/pretixbase/js/asynctask.js:276
#: pretix/static/pretixbase/js/asynctask.js:273
#: pretix/static/pretixcontrol/js/ui/main.js:71
msgid "Close message"
msgstr ""
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-07-01 07:50+0000\n"
"POT-Creation-Date: 2022-06-09 15:47+0000\n"
"PO-Revision-Date: 2019-08-27 08:00+0000\n"
"Last-Translator: Bostjan Marusic <bostjan@brokenbones.si>\n"
"Language-Team: Slovenian <https://translate.pretix.eu/projects/pretix/pretix-"
@@ -400,7 +400,7 @@ msgstr ""
"preverite vašo internetno povezavo in nato ponovno naložite spletno stran in "
"poskusite znova."
#: pretix/static/pretixbase/js/asynctask.js:276
#: pretix/static/pretixbase/js/asynctask.js:273
#: pretix/static/pretixcontrol/js/ui/main.js:71
msgid "Close message"
msgstr "Zapri obvestilo"

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