Compare commits

..
Author SHA1 Message Date
Lukas Bockstaller 14688c5c79 replace user_cancel_allowed internals 2026-09-01 17:25:16 +02:00
Lukas Bockstaller f5ad09233c Merge branch 'master' into self-service-storno 2026-08-31 15:09:47 +02:00
Lukas Bockstaller 622858314a repair tests 2026-08-21 16:40:03 +02:00
Lukas Bockstaller 83cb12281f repair bodged merge 2026-08-21 16:37:26 +02:00
Lukas Bockstaller afac250fdc fix stuff that broke 2026-08-21 15:36:28 +02:00
Lukas Bockstaller 6bd2c5584a Merge branch 'master' into self-service-storno 2026-08-21 15:31:11 +02:00
Lukas Bockstaller 701a09eaf9 isort 2026-08-21 15:30:51 +02:00
Lukas Bockstaller 340994d12c implement todos 2026-08-21 14:40:35 +02:00
Lukas Bockstaller 7ca6a954eb add review state 2026-08-21 14:40:25 +02:00
Lukas Bockstaller f0cadd75dd introduce cancellation model and cleanup duplication 2026-08-21 13:24:22 +02:00
Lukas Bockstaller 59ab88eb7b cleanup 2026-08-21 12:22:40 +02:00
Lukas Bockstaller 0b9a455817 add tests for PositionCancellationRule 2026-08-19 14:20:14 +02:00
Lukas Bockstaller 74ff52f6a0 introduce missing check_ts everywhere and restructure tests 2026-08-19 10:21:31 +02:00
Lukas Bockstaller 67d1ac7949 implement evaluate_position_rule 2026-08-18 17:29:43 +02:00
Lukas Bockstaller 4c8187e837 implement evaluate_process_rule 2026-08-18 16:56:53 +02:00
Lukas Bockstaller 577b9b5737 Merge branch 'master' into self-service-storno 2026-08-14 08:08:28 +02:00
Lukas Bockstaller 1e561a8a10 small cleanup 2026-08-13 11:39:29 +02:00
Lukas Bockstaller e56aa3d10f only one table 2026-08-13 11:39:19 +02:00
Lukas Bockstaller 5c57c9706e tests 2026-07-20 16:51:56 +02:00
Lukas Bockstaller cc280d5f6c prefetching and documenting stuff 2026-07-09 17:15:11 +02:00
Lukas Bockstaller a6b5cef3b6 big restructuring and conceptual cleanup 2026-07-08 17:50:01 +02:00
Lukas Bockstaller 7761387d07 Merge branch 'master' into self-service-storno 2026-07-06 12:53:57 +02:00
Lukas Bockstaller 2e673b5e49 wip 2026-04-15 11:48:32 +02:00
Lukas Bockstaller 5ab3b08fca cleanup
# Conflicts:
#	src/pretix/base/services/orders.py
2026-04-15 11:47:13 +02:00
Lukas Bockstaller c624fcfe41 move checks to classes and add distinction between process_fees and position fees 2026-04-15 11:15:01 +02:00
Lukas BockstallerandRaphael Michel 7ffadb87b3 Apply suggestions from code review
Co-authored-by: Raphael Michel <mail@raphaelmichel.de>
2026-04-15 11:15:01 +02:00
Lukas Bockstaller c1db94dec3 clean up 2026-04-15 11:15:01 +02:00
Lukas Bockstaller 9224c73c7f wip 2026-04-15 11:15:01 +02:00
Lukas Bockstaller 1bb2ab28ad wip 2026-04-15 11:15:01 +02:00
Lukas Bockstaller accfc843d6 wip 2026-04-15 11:15:00 +02:00
340 changed files with 38246 additions and 37777 deletions
-2
View File
@@ -1,2 +0,0 @@
# Format pre-vue code with eslint where possible (2026-09-10)
d85e52c83ed3639e040372fd0052e842e4899d90
+2 -1
View File
@@ -16,6 +16,8 @@ recursive-include src/pretix/plugins/banktransfer/templates *
recursive-include src/pretix/plugins/banktransfer/static *
recursive-include src/pretix/plugins/manualpayment/templates *
recursive-include src/pretix/plugins/manualpayment/static *
recursive-include src/pretix/plugins/paypal/templates *
recursive-include src/pretix/plugins/paypal/static *
recursive-include src/pretix/plugins/paypal2/templates *
recursive-include src/pretix/plugins/paypal2/static *
recursive-include src/pretix/plugins/src/pretixdroid/templates *
@@ -42,7 +44,6 @@ recursive-include src *.py
recursive-include src *.svg
recursive-include src *.txt
recursive-include src Makefile
recursive-include src *.pdf
recursive-exclude doc *
recursive-exclude deployment *
+2 -2
View File
@@ -53,8 +53,6 @@ Checking a ticket in
Defaults to ``false`` in which case the server will determine the language (currently
the event default language, might change in the future with support for the
``Accept-Language`` header).
:<json boolean simulate: Do not actually perform the check-in, only simulate the response. The ``position`` response
object will not reflect the simulated changes.
:>json string status: ``"ok"``, ``"incomplete"``, ``"exchange"``, or ``"error"``
:>json string reason: Reason code, only set on status ``"error"``, see below for possible values.
:>json string reason_explanation: Human-readable explanation, only set on status ``"error"`` and reason ``"rules"``, can be null.
@@ -73,6 +71,8 @@ Checking a ticket in
:>json object questions: List of questions to be answered for check-in, only set on status ``"incomplete"``.
:>json object media_policy: Reusable media policy (see documentation on items), only set on status ``"exchange"``.
:>json object media_type: Reusable media type (see documentation on items), only set on status ``"exchange"``.
:>json boolean simulate: Do not actually perform the check-in, only simulate the response. The ``position`` response
object will not reflect the simulated changes.
**Example request**:
-241
View File
@@ -1,241 +0,0 @@
Event Meta Properties
=====================
Resource description
--------------------
An event meta property is used to to define meta information fields for its events.
This information can be re-used, for example, in ticket layouts.
The event meta property resource contains the following public fields:
.. rst-class:: rest-resource-table
===================================== ========================== =======================================================
Field Type Description
===================================== ========================== =======================================================
id integer Unique ID for this property
name string Name of the property
default string Value of the default option
required boolean If ``true``, an event can only be taken live if the
property is set. In event series, it's always optional
to set a value for individual dates
protected boolean If ``true``, the value for an event can only be changed
by organizer-level administrators
filter_public boolean If ``true``, this property will be shown to filter
events in the public event list and calendar
public_label string Public name of the property
filter_allowed boolean If ``true``, this property will be shown to filter
events or reports in the backend, and it can also be
used for hidden filter parameters in the frontend
choices list of objects List of JSON objects representing all permitted values
for this property, or ``null`` for no limitation.
Each choice object has a required internal name named
``key`` and optional public name named ``label``
consisting of a dictionary of i18n string translations
===================================== ========================== =======================================================
Endpoints
---------
.. http:get:: /api/v1/organizers/(organizer)/event_meta_properties/
Returns a list of all meta properties for the organizer.
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/bigevents/meta_properties/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: application/json
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"id": 1,
"name": "Color",
"default": "blue",
"required": false,
"protected": false,
"filter_public": false,
"public_label": {},
"filter_allowed": true,
"choices": [
{
"key": "blue",
"label": {
"en": "Blue"
},
}
]
}
]
}
:param organizer: The ``slug`` field of the organizer
:statuscode 200: no error
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer does not exist **or** you have no permission to view this resource.
.. http:get:: /api/v1/organizers/(organizer)/event_meta_properties/(id)/
Returns information on one property, identified by its id.
**Example request**:
.. sourcecode:: http
GET /api/v1/organizers/bigevents/event_meta_properties/1/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
**Example response**:
.. sourcecode:: http
{
"id": 1,
"name": "Color",
"default": "blue",
"required": false,
"protected": false,
"filter_public": false,
"public_label": {},
"filter_allowed": true,
"choices": null
}
:param organizer: The ``slug`` field of the organizer
:param id: The ``id`` field of the meta property to retrieve
:statuscode 200: no error
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer does not exist **or** you have no permission to view this resource.
.. http:post:: /api/v1/organizers/(organizer)/event_meta_properties/
Creates a new meta property
**Example request**:
.. sourcecode:: http
POST /api/v1/organizers/bigevents/event_meta_properties/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
Content-Type: application/json
{
"name": "ref-code",
"default": "abcde",
"required": true,
"choices": null
}
**Example response**:
.. sourcecode:: http
{
"id": 2,
"name": "reference",
"default": "abcde",
"required": true,
"protected": false,
"filter_public": false,
"public_label": null,
"filter_allowed": true,
"choices": null
}
:param organizer: The ``slug`` field of the organizer
:statuscode 201: no error
:statuscode 400: The meta property could not be created due to invalid submitted data.
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer does not exist **or** you have no permission to create this resource.
.. http:patch:: /api/v1/organizers/(organizer)/event_meta_properties/(id)/
Update a meta property. You can also use ``PUT`` instead of ``PATCH``. With ``PUT``, you have to provide
all fields of the resource, other fields will be reset to default. With ``PATCH``, you only need to provide the
fields that you want to change.
You can change all fields of the resource except the ``id`` field.
**Example request**:
.. sourcecode:: http
PATCH /api/v1/organizers/bigevents/event_meta_properties/2/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
Content-Type: application/json
Content-Length: 94
{
"required": false
}
**Example response**:
.. sourcecode:: http
HTTP/1.1 200 OK
Vary: Accept
Content-Type: application/json
{
"id": 3,
"name": "reference",
"default": "abcde",
"required": false,
"protected": false,
"filter_public": false,
"public_label": null,
"filter_allowed": true,
"choices": null
}
:param organizer: The ``slug`` field of the organizer
:param id: The ``id`` field of the meta property to modify
:statuscode 200: no error
:statuscode 400: The property could not be modified due to invalid submitted data
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer does not exist **or** you have no permission to change this resource.
.. http:delete:: /api/v1/organizers/(organizer)/event_meta_properties/(id)/
Delete a meta property.
**Example request**:
.. sourcecode:: http
DELETE /api/v1/organizers/bigevents/event_meta_properties/1/ 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 the organizer
:param id: The ``id`` field of the meta property to delete
:statuscode 204: no error
:statuscode 401: Authentication failure
:statuscode 403: The requested organizer does not exist **or** you have no permission to delete this resource.
+15 -17
View File
@@ -110,7 +110,7 @@ Endpoints
"plugins": [
"pretix.plugins.banktransfer",
"pretix.plugins.stripe",
"pretix.plugins.paypal2",
"pretix.plugins.paypal",
"pretix.plugins.ticketoutputpdf"
],
"all_sales_channels": false,
@@ -199,7 +199,7 @@ Endpoints
"plugins": [
"pretix.plugins.banktransfer",
"pretix.plugins.stripe",
"pretix.plugins.paypal2",
"pretix.plugins.paypal",
"pretix.plugins.ticketoutputpdf"
],
"valid_keys": {
@@ -262,7 +262,7 @@ Endpoints
"item_meta_properties": {},
"plugins": [
"pretix.plugins.stripe",
"pretix.plugins.paypal2"
"pretix.plugins.paypal"
],
"all_sales_channels": true,
"limit_sales_channels": []
@@ -299,7 +299,7 @@ Endpoints
"item_meta_properties": {},
"plugins": [
"pretix.plugins.stripe",
"pretix.plugins.paypal2"
"pretix.plugins.paypal"
],
"all_sales_channels": true,
"limit_sales_channels": [],
@@ -364,7 +364,7 @@ Endpoints
"item_meta_properties": {},
"plugins": [
"pretix.plugins.stripe",
"pretix.plugins.paypal2"
"pretix.plugins.paypal"
],
"all_sales_channels": true,
"limit_sales_channels": []
@@ -401,7 +401,7 @@ Endpoints
"item_meta_properties": {},
"plugins": [
"pretix.plugins.stripe",
"pretix.plugins.paypal2"
"pretix.plugins.paypal"
],
"all_sales_channels": true,
"limit_sales_channels": [],
@@ -438,7 +438,7 @@ Endpoints
"plugins": [
"pretix.plugins.banktransfer",
"pretix.plugins.stripe",
"pretix.plugins.paypal2",
"pretix.plugins.paypal",
"pretix.plugins.pretixdroid"
]
}
@@ -475,7 +475,7 @@ Endpoints
"plugins": [
"pretix.plugins.banktransfer",
"pretix.plugins.stripe",
"pretix.plugins.paypal2",
"pretix.plugins.paypal",
"pretix.plugins.pretixdroid"
],
"all_sales_channels": true,
@@ -566,7 +566,7 @@ organizer level.
Content-Type: application/json
{
"region": "DE",
"imprint_url": "https://pretix.eu",
…
}
@@ -579,14 +579,12 @@ organizer level.
Content-Type: application/json
{
"region":
"imprint_url":
{
"value": "DE",
"label": "Region",
"value": "https://pretix.eu",
"label": "Imprint URL",
"readonly": false,
"help_text": "Will be used to determine date and time formatting as well as default country for customer
addresses and phone numbers. For formatting, this takes less priority than the language and
is therefore mostly relevant for languages used in different regions globally (like English)."
"help_text": "This should point e.g. to a part of your website that has your contact details and legal information."
}
},
…
@@ -622,7 +620,7 @@ organizer level.
Content-Type: application/json
{
"region": "DE"
"imprint_url": "https://example.org/imprint/"
}
**Example response**:
@@ -634,7 +632,7 @@ organizer level.
Content-Type: application/json
{
"region": "DE",
"imprint_url": "https://example.org/imprint/",
…
}
-1
View File
@@ -12,7 +12,6 @@ at :ref:`plugin-docs`.
organizers
events
subevents
event_meta_properties
taxrules
categories
items
-1
View File
@@ -116,7 +116,6 @@ Endpoints
:query integer page: The page number in case of a multi-page result set, default is 1
:query string code: Only show the voucher with the given voucher code.
:query string search: Only show the voucher with the given query found in the code, tag, or comment.
:query integer max_usages: Only show vouchers with the given maximal number of usages.
:query integer redeemed: Only show vouchers with the given number of redemptions. Note that this doesn't tell you if
the voucher can still be redeemed, as this also depends on ``max_usages``. See the
+1 -1
View File
@@ -15,7 +15,7 @@ Core
item_copy_data, register_sales_channel_types, register_global_settings, quota_availability, global_email_filter,
register_ticket_secret_generators, gift_card_transaction_display,
register_text_placeholders, register_mail_placeholders, device_info_updated,
register_event_permission_groups, register_organizer_permission_groups
register_event_permission_groups, register_organizer_permission_groups, self_service_cancellation_checks
Order events
""""""""""""
+1 -57
View File
@@ -8,63 +8,7 @@ import vuePug from 'eslint-plugin-vue-pug'
const ignores = globalIgnores([
'**/node_modules',
'**/dist',
// Vendored code
'src/pretix/static/leaflet',
'src/pretix/static/clipboard',
'src/pretix/static/cropper',
'src/pretix/static/lightbox',
'src/pretix/static/are-you-sure',
'src/pretix/static/vuejs',
'src/pretix/static/fontawesome',
'src/pretix/static/typeahead',
'src/pretix/static/moment',
'src/pretix/static/pdfjs',
'src/pretix/static/sortable',
'src/pretix/static/iframeresizer',
'src/pretix/static/bootstrap',
'src/pretix/static/d3',
'src/pretix/static/jsi18n',
'src/pretix/static/fabric',
'src/pretix/static/datetimepicker',
'src/pretix/static/charts',
'src/pretix/static/fileupload',
'src/pretix/static/seating',
'src/pretix/static/rest_framework',
'src/pretix/static/select2',
'src/pretix/static/schema',
'src/pretix/static/slider',
'src/pretix/static/jquery',
'src/pretix/static/colorpicker',
'src/pretix/static/rrule',
'src/pretix/static/pretixcontrol/js/jquery.qrcode.min.js',
'src/pretix/static/pretixpresale/js/widget/docready.js',
// Pre-vue JS code
'src/pretix/static/pretixbase/js/addressform.js',
'src/pretix/static/pretixbase/js/asynctask.js',
'src/pretix/static/pretixbase/js/details.js',
'src/pretix/static/pretixbase/js/gettextstub.js',
'src/pretix/static/pretixbase/js/i18nstring.js',
'src/pretix/static/pretixcontrol/js/menu.js',
'src/pretix/static/pretixcontrol/js/ui/editor.js',
'src/pretix/static/pretixcontrol/js/ui/geo.js',
'src/pretix/static/pretixcontrol/js/ui/main.js',
'src/pretix/static/pretixcontrol/js/ui/subevent.js',
'src/pretix/static/pretixcontrol/js/ui/variations.js',
'src/pretix/static/pretixcontrol/js/ui/webauthn.js',
'src/pretix/static/pretixpresale/js/ui/cart.js',
'src/pretix/static/pretixpresale/js/ui/main.js',
'src/pretix/static/pretixpresale/js/ui/questions.js',
'src/pretix/static/pretixpresale/js/widget/floatformat.js',
'src/pretix/static/pretixpresale/js/widget/widget.js',
'src/pretix/plugins/banktransfer/static',
'src/pretix/plugins/paypal2/static',
'src/pretix/plugins/statistics/static',
'src/pretix/plugins/stripe/static',
// Plugin checkouts
'local',
// docs
'doc',
'**/dist'
])
export default defineConfig([
+13 -27
View File
@@ -294,43 +294,29 @@
}
},
"node_modules/@humanfs/core": {
"version": "0.19.2",
"resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz",
"integrity": "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==",
"version": "0.19.1",
"resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
"integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@humanfs/types": "^0.15.0"
},
"engines": {
"node": ">=18.18.0"
}
},
"node_modules/@humanfs/node": {
"version": "0.16.8",
"resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.8.tgz",
"integrity": "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==",
"version": "0.16.7",
"resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz",
"integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@humanfs/core": "^0.19.2",
"@humanfs/types": "^0.15.0",
"@humanfs/core": "^0.19.1",
"@humanwhocodes/retry": "^0.4.0"
},
"engines": {
"node": ">=18.18.0"
}
},
"node_modules/@humanfs/types": {
"version": "0.15.0",
"resolved": "https://registry.npmjs.org/@humanfs/types/-/types-0.15.0.tgz",
"integrity": "sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==",
"dev": true,
"license": "Apache-2.0",
"engines": {
"node": ">=18.18.0"
}
},
"node_modules/@humanwhocodes/module-importer": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
@@ -3394,9 +3380,9 @@
}
},
"node_modules/postcss-selector-parser": {
"version": "7.1.5",
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.5.tgz",
"integrity": "sha512-KvvtD7SrlBP7dlgkBghEE3r84CABm5SmV2aNcG4oCA+qDnJ/tvKonFVvwWAyyWUEwxuNawdfEAZKP9zM3oZ2Uw==",
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz",
"integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4162,9 +4148,9 @@
}
},
"node_modules/smol-toml": {
"version": "1.7.1",
"resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.7.1.tgz",
"integrity": "sha512-PPlsspAZ4jbMBu5DMFhfUGDQLu/vrL4SyBROVS37x8ynnVmFIs1VPBz1Co8Xks3TvpIaZXmU85y4DrQ+UyVFoQ==",
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.6.1.tgz",
"integrity": "sha512-dWUG8F5sIIARXih1DTaQAX4SsiTXhInKf1buxdY9DIg4ZYPZK5nGM1VRIYmEbDbsHt7USo99xSLFu5Q1IqTmsg==",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
+12 -12
View File
@@ -33,14 +33,14 @@ dependencies = [
"bleach==6.4.*",
"celery==5.6.*",
"chardet==5.2.*",
"cryptography>=50.0.1",
"cryptography>=50.0.0",
"css-inline==0.21.*",
"defusedcsv>=3.0.0",
"dnspython==2.*",
"Django[argon2]==5.2.*,>=5.2.17",
"Django[argon2]==5.2.*",
"django-bootstrap3==26.2",
"django-compressor==4.6.0",
"django-countries==9.1.*",
"django-countries==9.0.*",
"django-filter==26.1",
"django-formset-js-improved==0.5.0.5",
"django-formtools==2.7",
@@ -56,7 +56,7 @@ dependencies = [
"django-querytagger==0.0.3",
"django-redis==7.0.*",
"django-scopes==2.1.*",
"django-statici18n==2.8.*",
"django-statici18n==2.7.*",
"djangorestframework==3.17.*",
"dnspython==2.8.*",
"drf_ujson2==1.7.*",
@@ -67,7 +67,7 @@ dependencies = [
"kombu==5.6.*",
"libsass==0.23.*",
"lxml",
"markdown==3.11", # 3.3.5 requires importlib-metadata>=4.4, but django-bootstrap3 requires importlib-metadata<3.
"markdown==3.10.3", # 3.3.5 requires importlib-metadata>=4.4, but django-bootstrap3 requires importlib-metadata<3.
# We can upgrade markdown again once django-bootstrap3 upgrades or once we drop Python 3.6 and 3.7
"mt-940==4.30.*",
"oauthlib==3.3.*",
@@ -75,7 +75,7 @@ dependencies = [
"packaging",
"paypalrestsdk==1.13.*",
"paypal-checkout-serversdk==1.0.*",
"PyJWT==2.15.*",
"PyJWT==2.13.*",
"phonenumberslite==9.0.*",
"Pillow==12.3.*",
"pretix-plugin-build",
@@ -84,7 +84,7 @@ dependencies = [
"pycountry",
"pycparser==3.0",
"pycryptodome==3.23.*",
"pypdf==6.19.*",
"pypdf==6.5.*",
"python-bidi==0.6.*", # Support for Arabic in reportlab
"python-dateutil==2.9.*",
"pytz",
@@ -94,7 +94,7 @@ dependencies = [
"redis==7.4.*",
"reportlab==5.0.*",
"requests==2.34.*",
"sentry-sdk==2.70.*",
"sentry-sdk==2.68.*",
"sepaxml==2.7.*",
"stripe==7.9.*",
"text-unidecode==1.*",
@@ -112,10 +112,10 @@ dev = [
"aiohttp==3.14.*",
"coverage",
"coveralls",
"fakeredis==2.38.*",
"flake8==7.4.*",
"fakeredis==2.37.*",
"flake8==7.3.*",
"freezegun",
"isort==9.0.*",
"isort==8.0.*",
"pep8-naming==0.15.*",
"potypo",
"pytest-asyncio>=1.4.0",
@@ -129,7 +129,7 @@ dev = [
"pytest==9.1.*",
"playwright",
"responses",
"pypdfium2"
"django-stubs-ext"
]
[project.entry-points."distutils.commands"]
+1
View File
@@ -26,6 +26,7 @@ ignore =
src/tests/plugins/*
src/tests/plugins/badges/*
src/tests/plugins/banktransfer/*
src/tests/plugins/paypal/*
src/tests/plugins/paypal2/*
src/tests/plugins/pretixdroid/*
src/tests/plugins/stripe/*
-2
View File
@@ -30,5 +30,3 @@ npminstall:
npmbuild:
npm run build
licenseheaders:
licenseheaders -t ../.licenseheader -E .py -x "*/migrations/*.py"
+1 -1
View File
@@ -19,4 +19,4 @@
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
# <https://www.gnu.org/licenses/>.
#
__version__ = "2026.8.0"
__version__ = "2026.8.0.dev0"
-4
View File
@@ -101,10 +101,6 @@ class OAuthAccessToken(AbstractAccessToken):
self.expires = now() - timedelta(hours=1)
self.save(update_fields=['expires'])
def is_valid(self, scopes=None):
# Can maybe be removed after upgrading django-oauth-toolkit to 3.4.1
return super().is_valid(scopes) and self.application.is_usable(None)
class OAuthRefreshToken(AbstractRefreshToken):
application = models.ForeignKey(
+1 -9
View File
@@ -37,8 +37,6 @@ from collections import OrderedDict
from django.core.exceptions import ValidationError
from rest_framework import serializers
from pretix.api.auth.utils import get_session_key_for_api_request
def remove_duplicates_from_list(data):
return list(OrderedDict.fromkeys(data))
@@ -85,16 +83,10 @@ class UploadedFileField(serializers.Field):
request = self.context.get('request', None)
try:
cf = CachedFile.objects.get(
session_key=f'api-upload-{str(type(request.user or request.auth))}-{(request.user or request.auth).pk}',
file__isnull=False,
pk=data[len("file:"):],
)
if cf.session_key == "api-upload-<class 'django.contrib.auth.models.AnonymousUser'>-None":
# OK, backwards-compatibility of a security bug fixed 2026-09, delete this at some point, but should
# also be harmless because all files with this key are expired one day after deployment of this fix
# and no new files with this key are created
pass
elif cf.session_key != get_session_key_for_api_request(request):
self.fail('not_found')
except (ValidationError, IndexError): # invalid uuid
self.fail('not_found')
except CachedFile.DoesNotExist:
+4 -10
View File
@@ -41,7 +41,6 @@ from rest_framework.exceptions import ValidationError
from rest_framework.relations import SlugRelatedField
from rest_framework.reverse import reverse
from pretix.api.auth.utils import get_session_key_for_api_request
from pretix.api.serializers import CompatDecimalField, CompatibleJSONField
from pretix.api.serializers.event import SubEventSerializer
from pretix.api.serializers.forms import form_field_to_serializer_field
@@ -259,21 +258,16 @@ class AnswerSerializer(I18nAwareModelSerializer):
if data['answer'] == 'file:keep':
return data
try:
ao = self.context["request"].user or self.context["request"].auth
cf = CachedFile.objects.get(
session_key=f'api-upload-{str(type(ao))}-{ao.pk}',
file__isnull=False,
pk=data['answer'][len("file:"):],
)
if cf.session_key == "api-upload-<class 'django.contrib.auth.models.AnonymousUser'>-None":
# OK, backwards-compatibility of a security bug fixed 2026-09, delete this at some point, but should
# also be harmless because all files with this key are expired one day after deployment of this fix
# and no new files with this key are created
pass
elif cf.session_key != get_session_key_for_api_request(self.context["request"]):
raise ValidationError('The submitted file ID "{fid}" was not found.'.format(fid=data['answer']))
except (ValidationError, IndexError): # invalid uuid
raise ValidationError('The submitted file ID "{fid}" was not found.'.format(fid=data['answer']))
raise ValidationError('The submitted file ID "{fid}" was not found.'.format(fid=data))
except CachedFile.DoesNotExist:
raise ValidationError('The submitted file ID "{fid}" was not found.'.format(fid=data['answer']))
raise ValidationError('The submitted file ID "{fid}" was not found.'.format(fid=data))
allowed_types = (
'image/png', 'image/jpeg', 'image/gif', 'application/pdf'
+3 -90
View File
@@ -28,7 +28,6 @@ from django.db import transaction
from django.db.models import Q
from django.utils.crypto import get_random_string
from django.utils.translation import gettext, gettext_lazy as _
from i18nfield.rest_framework import I18nField
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
@@ -41,10 +40,9 @@ from pretix.api.serializers.settings import SettingsSerializer
from pretix.base.auth import get_auth_backends
from pretix.base.i18n import get_language_without_region
from pretix.base.models import (
Customer, Device, EventMetaProperty, GiftCard, GiftCardAcceptance,
GiftCardTransaction, Membership, MembershipType, OrderPosition, Organizer,
ReusableMedium, SalesChannel, SeatingPlan, Team, TeamAPIToken, TeamInvite,
User,
Customer, Device, GiftCard, GiftCardAcceptance, GiftCardTransaction,
Membership, MembershipType, OrderPosition, Organizer, ReusableMedium,
SalesChannel, SeatingPlan, Team, TeamAPIToken, TeamInvite, User,
)
from pretix.base.models.seating import SeatingPlanLayoutValidator
from pretix.base.permissions import (
@@ -642,88 +640,3 @@ class OrganizerSettingsSerializer(SettingsSerializer):
)
# TODO: make sure pub is always correct
return 'pub/' + fname
class MetaPropertyListField(serializers.ListField):
def __init__(self, *args, **kwargs):
kwargs["validators"] = kwargs.pop("validators", [])
def validate_keys_unique(choices):
if not choices:
return
keys = [c.get("key") for c in choices]
if len(set(keys)) < len(keys):
raise ValidationError("The key for each meta property value option must be unique.")
kwargs["validators"].append(
validate_keys_unique
)
super().__init__(*args, **kwargs)
class MetaPropertyDictField(serializers.DictField):
def __init__(self, **kwargs):
self.label_child = kwargs.pop("label_child", I18nField())
super().__init__(**kwargs)
def to_representation(self, value):
# django added unneccessary keys DELETE, ORDER through formsets, filter them here for backwards compat
d = {
"key": value["key"]
}
if "label" in value:
d["label"] = self.label_child.to_representation(value["label"])
return super().to_representation(d)
def to_internal_value(self, data):
if not isinstance(data, dict):
raise ValidationError("Meta property value options must be a dict.")
if not isinstance(data.get("key"), str):
raise ValidationError("Meta property value options must have a key of type string.")
if any(k not in {"key", "label"} for k in data.keys()):
raise ValidationError("Meta property value options may only have a key and optionally a label.")
if "label" in data:
try:
data["label"] = self.label_child.to_internal_value(data["label"])
except ValidationError as e:
raise ValidationError({"label": e.detail})
return super().to_internal_value(data)
class EventMetaPropertiesSerializer(I18nAwareModelSerializer):
choices = MetaPropertyListField(
child=MetaPropertyDictField(
label_child=I18nField()
),
allow_null=True,
)
class Meta:
model = EventMetaProperty
fields = (
'id', 'name', 'default', 'required', 'protected', 'filter_public', 'public_label', 'filter_allowed',
'choices'
)
def validate(self, data):
data = super().validate(data)
full_data = self.to_internal_value(self.to_representation(self.instance)) if self.instance else {}
full_data.update(data)
choices = full_data.get("choices")
default = full_data.get("default")
if choices and default:
choice_keys = [c.get("key") for c in choices]
if default not in choice_keys:
raise ValidationError("You cannot set a default value that is not a valid value.")
if not choices and "choices" in data:
# normalize empty dict to None
data["choices"] = None
return data
-1
View File
@@ -68,7 +68,6 @@ orga_router.register(r'scheduled_exports', exporters.ScheduledOrganizerExportVie
orga_router.register(r'exporters', exporters.OrganizerExportersViewSet, basename='exporters')
orga_router.register(r'transactions', order.OrganizerTransactionViewSet)
orga_router.register(r'orderpositions', order.OrganizerOrderPositionViewSet, basename='orderpositions')
orga_router.register(r'event_meta_properties', organizer.EventMetaPropertiesViewSet)
team_router = routers.DefaultRouter()
team_router.register(r'members', organizer.TeamMemberViewSet)
+1 -8
View File
@@ -50,7 +50,6 @@ from rest_framework.generics import ListAPIView
from rest_framework.permissions import SAFE_METHODS
from rest_framework.response import Response
from pretix.api.auth.utils import get_session_key_for_api_auth
from pretix.api.serializers.checkin import (
CheckinListSerializer, CheckinRPCAnnulInputSerializer,
CheckinRPCRedeemInputSerializer, MiniCheckinListSerializer,
@@ -332,16 +331,10 @@ with scopes_disabled():
def _handle_file_upload(data, user, auth):
try:
cf = CachedFile.objects.get(
session_key=f'api-upload-{str(type(user or auth))}-{(user or auth).pk}',
file__isnull=False,
pk=data[len("file:"):],
)
if cf.session_key == "api-upload-<class 'django.contrib.auth.models.AnonymousUser'>-None":
# OK, backwards-compatibility of a security bug fixed 2026-09, delete this at some point, but should
# also be harmless because all files with this key are expired one day after deployment of this fix
# and no new files with this key are created
pass
elif cf.session_key != get_session_key_for_api_auth(user, auth):
raise ValidationError('The submitted file ID "{fid}" was not found.'.format(fid=data))
except (ValidationError, BaseValidationError, IndexError): # invalid uuid
raise ValidationError('The submitted file ID "{fid}" was not found.'.format(fid=data))
except CachedFile.DoesNotExist:
+4 -51
View File
@@ -44,16 +44,15 @@ from pretix.api.models import OAuthAccessToken
from pretix.api.pagination import TotalOrderingFilter
from pretix.api.serializers.organizer import (
CustomerCreateSerializer, CustomerSerializer, DeviceSerializer,
EventMetaPropertiesSerializer, GiftCardSerializer,
GiftCardTransactionSerializer, MembershipSerializer,
GiftCardSerializer, GiftCardTransactionSerializer, MembershipSerializer,
MembershipTypeSerializer, OrganizerSerializer, OrganizerSettingsSerializer,
SalesChannelSerializer, SeatingPlanSerializer, TeamAPITokenSerializer,
TeamInviteSerializer, TeamMemberSerializer, TeamSerializer,
)
from pretix.base.models import (
Customer, Device, Event, EventMetaProperty, GiftCard, GiftCardTransaction,
LogEntry, Membership, MembershipType, Organizer, SalesChannel, SeatingPlan,
Team, TeamAPIToken, TeamInvite, User,
Customer, Device, Event, GiftCard, GiftCardTransaction, LogEntry,
Membership, MembershipType, Organizer, SalesChannel, SeatingPlan, Team,
TeamAPIToken, TeamInvite, User,
)
from pretix.base.plugins import (
PLUGIN_LEVEL_EVENT, PLUGIN_LEVEL_EVENT_ORGANIZER_HYBRID,
@@ -847,49 +846,3 @@ class SalesChannelViewSet(viewsets.ModelViewSet):
data={'id': instance.pk}
)
instance.delete()
class EventMetaPropertiesViewSet(viewsets.ModelViewSet):
serializer_class = EventMetaPropertiesSerializer
queryset = EventMetaProperty.objects.none()
write_permission = 'organizer.settings.general:write'
def get_queryset(self):
return self.request.organizer.meta_properties.all()
def get_serializer_context(self):
ctx = super().get_serializer_context()
ctx['organizer'] = self.request.organizer
return ctx
@transaction.atomic()
def perform_destroy(self, instance):
instance.log_action(
'pretix.property.deleted',
user=self.request.user,
auth=self.request.auth,
data={'id': instance.pk}
)
instance.delete()
@transaction.atomic()
def perform_create(self, serializer):
inst = serializer.save(organizer_id=self.request.organizer.pk)
serializer.instance.log_action(
'pretix.property.created',
user=self.request.user,
auth=self.request.auth,
data=self.request.data,
)
return inst
@transaction.atomic()
def perform_update(self, serializer):
inst = serializer.save(organizer_id=self.request.organizer.pk)
serializer.instance.log_action(
'pretix.property.changed',
user=self.request.user,
auth=self.request.auth,
data=self.request.data,
)
return inst
+1 -2
View File
@@ -33,7 +33,6 @@ from rest_framework.views import APIView
from pretix.api.auth.device import DeviceTokenAuthentication
from pretix.api.auth.permission import AnyAuthenticatedClientPermission
from pretix.api.auth.token import TeamTokenAuthentication
from pretix.api.auth.utils import get_session_key_for_api_request
from pretix.base.models import CachedFile
from pretix.helpers.images import (
IMAGE_TYPES, validate_uploaded_file_for_valid_image,
@@ -79,7 +78,7 @@ class UploadView(APIView):
web_download=False,
filename=file_obj.name,
type=content_type,
session_key=get_session_key_for_api_request(request)
session_key=f'api-upload-{str(type(request.user or request.auth))}-{(request.user or request.auth).pk}'
)
cf.file.save(file_obj.name, file_obj)
cf.save()
-4
View File
@@ -40,7 +40,6 @@ with scopes_disabled():
class VoucherFilter(FilterSet):
active = BooleanFilter(method='filter_active')
code = CharFilter(lookup_expr='iexact')
search = CharFilter(method='search_qs')
class Meta:
model = Voucher
@@ -55,9 +54,6 @@ with scopes_disabled():
return queryset.filter(Q(redeemed__gte=F('max_usages')) |
(Q(valid_until__isnull=False) & Q(valid_until__lte=now())))
def search_qs(self, qs, name, value):
return qs.filter(Q(code__icontains=value) | Q(tag__icontains=value) | Q(comment__icontains=value))
class VoucherViewSet(viewsets.ModelViewSet):
serializer_class = VoucherSerializer
+3 -7
View File
@@ -27,7 +27,7 @@ from datetime import timedelta
from functools import cached_property
from typing import List, Optional, Protocol
from django.conf import settings
import sentry_sdk
from django.db import DatabaseError, transaction
from django.utils.timezone import now
from django.utils.translation import gettext_lazy as _
@@ -236,9 +236,7 @@ class OutboundSyncProvider:
# model changes saved by set_sync_error / clear_in_flight calls below
if sq.failed_attempts >= self.max_attempts:
logger.exception('Failed to sync order (max attempts exceeded)')
if settings.SENTRY_ENABLED:
import sentry_sdk
sentry_sdk.capture_exception(e)
sentry_sdk.capture_exception(e)
sq.set_sync_error("exceeded", e.messages, e.full_message)
else:
logger.info(
@@ -249,9 +247,7 @@ class OutboundSyncProvider:
sq.clear_in_flight()
except Exception as e:
logger.exception('Failed to sync order (unhandled exception)')
if settings.SENTRY_ENABLED:
import sentry_sdk
sentry_sdk.capture_exception(e)
sentry_sdk.capture_exception(e)
sq.set_sync_error("internal", [], str(e))
@cached_property
+4 -27
View File
@@ -54,7 +54,6 @@ from ...control.forms.filter import get_all_payment_providers
from ...helpers import GroupConcat
from ...helpers.iter import chunked_iterable
from ..exporter import BaseExporter, MultiSheetListExporter
from ..invoicing.transmission import get_transmission_types
from ..services.export import ExportError
from ..services.invoices import invoice_pdf_task
from ..signals import (
@@ -198,7 +197,7 @@ class InvoiceDataExporter(InvoiceExporterMixin, MultiSheetListExporter):
def iterate_sheet(self, form_data, sheet):
_ = gettext
if sheet == 'invoices':
headers = [
yield [
_('Invoice number'),
_('Date'),
_('Order code'),
@@ -231,18 +230,8 @@ class InvoiceDataExporter(InvoiceExporterMixin, MultiSheetListExporter):
_('Total value (without taxes)'),
_('Payment matching IDs'),
_('Payment providers'),
_('Transmission type'),
_('Transmission status'),
_('Transmission date'),
]
transmission_types = get_transmission_types()
for tt in transmission_types:
for c in tt.describe_info_columns():
headers.append(str(tt.verbose_name) + ': ' + str(c))
yield headers
p_providers = OrderPayment.objects.filter(
order=OuterRef('order'),
state__in=(OrderPayment.PAYMENT_STATE_CONFIRMED, OrderPayment.PAYMENT_STATE_REFUNDED,
@@ -253,7 +242,7 @@ class InvoiceDataExporter(InvoiceExporterMixin, MultiSheetListExporter):
'm'
).order_by()
base_qs = self.invoices_queryset(form_data)
base_qs = self.invoices_queryset(form_data)\
qs = base_qs.select_related(
'order', 'refers'
@@ -291,7 +280,7 @@ class InvoiceDataExporter(InvoiceExporterMixin, MultiSheetListExporter):
if mid:
pmis.append(mid)
pmi = '\n'.join(pmis)
line = [
yield [
i.full_invoice_no,
date_format(i.date, "SHORT_DATE_FORMAT"),
i.order.code,
@@ -326,20 +315,8 @@ class InvoiceDataExporter(InvoiceExporterMixin, MultiSheetListExporter):
', '.join([
str(self.providers.get(p, p)) for p in sorted(set((i.payment_providers or '').split(',')))
if p and p != 'free'
]),
i.transmission_type_instance.verbose_name,
i.get_transmission_status_display(),
date_format(i.transmission_date, "SHORT_DATETIME_FORMAT") if i.transmission_date else "",
])
]
for tt in transmission_types:
if tt.identifier == i.transmission_type:
described = dict(tt.describe_info(i.invoice_to_transmission_info, i.invoice_to_country, i.invoice_to_is_business))
for c in tt.describe_info_columns():
line.append(described.get(c, ""))
else:
for c in tt.describe_info_columns():
line.append("")
yield line
elif sheet == 'lines':
yield [
_('Invoice number'),
+17 -30
View File
@@ -350,22 +350,16 @@ class WrappedPhonePrefixSelect(Select):
return super().render(name, value or self.initial, *args, **kwargs)
def get_context(self, name, value, attrs):
# self.choices is lazy evaluated, needs to be realized to be modifiable
choices = list(self.choices)
if value and choices[1][0] != value:
matching_choices = len([1 for p, c in choices if p == value])
if value and self.choices[1][0] != value:
matching_choices = len([1 for p, c in self.choices if p == value])
if matching_choices > 1:
# Some countries share a phone prefix, for example +1 is used all over the Americas.
# This causes a UX problem: If the default value or the existing data is +12125552368,
# the widget will just show the first <option> entry with value="+1" as selected,
# which alphabetically is America Samoa, although most numbers statistically are from
# the US. As a workaround, we detect this case and add an additional choice value with
# the US. As a workaround, we detect this case and add an aditional choice value with
# just <option value="+1">+1</option> without an explicit country.
self.choices = [
choices[0],
(value, value),
*choices[1:],
]
self.choices.insert(1, (value, value))
context = super().get_context(name, value, attrs)
return context
@@ -600,16 +594,12 @@ class PortraitImageField(SizeValidationMixin, ExtValidationMixin, forms.FileFiel
image = ImageOps.exif_transpose(image)
if f._cropdata:
left = int(f._cropdata.get('x', 0))
top = int(f._cropdata.get('y', 0))
right = left + int(f._cropdata.get('width', image.width))
bottom = top + int(f._cropdata.get('height', image.height))
if left >= image.width or top >= image.height or right > image.width or bottom > image.height:
raise ValidationError(
self.error_messages['max_dimension'],
code='max_dimension',
)
image = image.crop((left, top, right, bottom))
image = image.crop((
f._cropdata.get('x', 0),
f._cropdata.get('y', 0),
f._cropdata.get('x', 0) + f._cropdata.get('width', image.width),
f._cropdata.get('y', 0) + f._cropdata.get('height', image.height),
))
with BytesIO() as output:
# This might use a lot of memory, but temporary files are not a good option since
# we don't control the cleanup
@@ -909,7 +899,7 @@ class BaseQuestionsForm(forms.Form):
field.widget.attrs['data-question-dependency-values'] = escapejson_attr(json.dumps(q.dependency_values))
if q.type != 'M':
field.widget.attrs['required'] = q.required and not self.all_optional
field._required = q.required and not self.all_optional
field._required = q.required and not self.all_optional
field.required = False
return field
@@ -1206,9 +1196,8 @@ class TicketLevelQuestionsForm(BaseQuestionsForm):
return field
def clean(self):
from pretix.base.addressvalidation import ( # local import to prevent impact on startup time
validate_address,
)
from pretix.base.addressvalidation import \
validate_address # local import to prevent impact on startup time
d = super().clean()
@@ -1449,9 +1438,8 @@ class BaseInvoiceAddressForm(forms.ModelForm):
self.fields['transmission_type'].widget.attrs['data-trigger-address-info'] = 'on'
def clean(self):
from pretix.base.addressvalidation import ( # local import to prevent impact on startup time
validate_address,
)
from pretix.base.addressvalidation import \
validate_address # local import to prevent impact on startup time
data = self.cleaned_data
@@ -1505,12 +1493,11 @@ class BaseInvoiceAddressForm(forms.ModelForm):
"vat_id": _("This field is required.")
})
if self.validate_vat_id and self.instance.vat_id_validated and not any(v in self.changed_data for v in ('is_business', 'vat_id', 'country')):
if self.validate_vat_id and self.instance.vat_id_validated and 'vat_id' not in self.changed_data:
pass # Skip re-validation if it is validated
elif self.validate_vat_id and vat_id_applicable:
try:
requester_id = self.request.event.settings.invoice_address_from_vat_id
normalized_id = validate_vat_id(data.get('vat_id'), str(data.get('country')), requester_id)
normalized_id = validate_vat_id(data.get('vat_id'), str(data.get('country')))
self.instance.vat_id_validated = bool(normalized_id)
self.instance.vat_id = data['vat_id'] = normalized_id
except VATIDFinalError as e:
+2 -2
View File
@@ -82,8 +82,8 @@ class UserSettingsForm(forms.ModelForm):
class User2FADeviceAddForm(forms.Form):
name = forms.CharField(label=_('Device name'), max_length=64)
devicetype = forms.ChoiceField(label=_('Device type'), widget=forms.RadioSelect, choices=(
('otp_totp.totpdevice', _('Smartphone with the Authenticator application')),
('pretixbase.webauthndevice', _('WebAuthn-compatible hardware token (e.g. Yubikey)')),
('totp', _('Smartphone with the Authenticator application')),
('webauthn', _('WebAuthn-compatible hardware token (e.g. Yubikey)')),
))
@@ -107,9 +107,6 @@ class TransmissionType:
def transmission_info_to_form_data(self, transmission_info: dict) -> dict:
return transmission_info
def describe_info_columns(self):
return [f.label for f in self.invoice_address_form_fields.values()]
def describe_info(self, transmission_info: dict, country: Country, is_business: bool):
form_data = self.transmission_info_to_form_data(transmission_info)
data = []
@@ -1,49 +0,0 @@
# Generated by Django 5.2.17 on 2026-09-21 11:30
import django.db.models.deletion
from django.db import migrations, models
def fix_unshredded_invoices(apps, _):
Invoice = apps.get_model("pretixbase", "Invoice")
InvoiceLine = apps.get_model("pretixbase", "InvoiceLine")
ignore_fields = (
# bool/int fields are not listed and skipped automatically
'prefix', 'invoice_no', 'full_invoice_no', 'invoice_from', 'invoice_from_name', 'invoice_from_zipcode',
'invoice_from_city', 'invoice_from_state', 'invoice_from_country', 'invoice_from_tax_id',
'invoice_from_vat_id', 'locale', 'payment_provider_stamp', 'footer_text', 'foreign_currency_display',
'foreign_currency_source', 'transmission_type', 'transmission_provider', 'transmission_status',
)
for i in Invoice.objects.filter(shredded=True):
for f in Invoice._meta.fields:
if f.name in ignore_fields:
continue
val = getattr(i, f.name, None)
if val and isinstance(val, str):
setattr(i, f.name, "█")
elif val and isinstance(val, list): # jsonfield
setattr(i, f.name, [])
elif val and isinstance(val, dict): # jsonfield
setattr(i, f.name, {"_shredded": True})
i.save()
InvoiceLine.objects.filter(
attendee_name__isnull=False,
invoice__shredded=True
).update(attendee_name="█")
class Migration(migrations.Migration):
dependencies = [
("pretixbase", "0310_question_valid_string_length_min"),
]
operations = [
migrations.RunPython(
fix_unshredded_invoices,
migrations.RunPython.noop,
),
]
+905
View File
@@ -0,0 +1,905 @@
import datetime
import operator
from dataclasses import asdict, dataclass, field
from decimal import Decimal
from itertools import chain
from typing import (
TYPE_CHECKING, Any, Callable, ClassVar, Dict, Final, List, Literal,
Optional, Protocol, Set, Tuple, TypeAlias,
)
from django.core.exceptions import ValidationError
from django.core.serializers.json import DjangoJSONEncoder
from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models
from django.db.models import Prefetch, QuerySet
from django.utils.timezone import make_aware
from django.utils.translation import gettext_lazy as _
from django_stubs_ext import StrOrPromise
from pretix.base.decimal import round_decimal
from pretix.base.models import Event, Item, ItemVariation, Order, OrderPosition
from pretix.base.reldate import ModelRelativeDateTimeField, RelativeDateWrapper
from pretix.base.signals import self_service_cancellation_checks
from pretix.helpers import ensure_no_queries
"""
Supporting self-service cancellation requires us to do two main things:
1. uphold the business logic of pretix and the installed plugins
2. charge the customer the appropriate fees for their cancellation
Number 1 is a question of bringing enough checks into place and prevent a
cancellation if one of them is violated.
Checks need to subclass `CancellationCheck` and can be provided via the new
`self_service_cancellation_checks` signal.
Number 2 is trickier because organizers will have complex^(TM) cancellation
fee structures and expressing these in an understandable way is a challenge.
Especially when taking support cases into consideration that have to debug
certain behaviour long after.
The cancellation fees are computed via `CancellationRules`.
When a customer triggers a self service cancellation, we will:
1. Positions
a. Evaluate all `CancellationChecks` that are concerned with individual positions
b. Evaluate all `CancellationRules` that are concerned with individual positions and compute the fees
c. Choose for each position the cheapest `CancellationRules` position result available
2. Process
a. Evaluate all `CancellationChecks` that are concerned with the process of cancellation
b. Evaluate all `CancellationRules` that are concerned with the process of cancellation
c. Choose the cheapest `CancellationRules` process result available
3. Return all results for Checks and Rules
Step 1c. and 2c. are kept separate intentionally.
The alternative of finding the cheapest cancellation option overall (process and position) would
require us to check the full combinatorics of possible process and position fees, resulting
in unfeasible runtime behaviour, and if we would optimize it in difficult to explain non-optimal
situations.
"""
class FeeType(models.TextChoices):
"""
Process fees can be added on top of all position fees, or they
can set a floor for the minimum cancellation fee that this will incur.
"""
MINIMUM = "min_process_fee", _("Minimum total fee")
ADDITIONAL = "add_process_fee", _("Additional fee")
POSITION = "position_fee", _("Position fee")
class CheckTypes(models.TextChoices):
POSITION = "position", _("Order Position Cancellation Rule")
PROCESS = "process", _("Cancellation Process Rule")
@dataclass(frozen=True)
class CheckResult:
"""
Result of an individual cancellation check.
The check result only encodes if the check allows or disallows cancellation via
`cancellation_possible`
"""
id: str
reason: StrOrPromise
cancellation_possible: bool
type: Literal['check'] = field(default="check")
@classmethod
def from_dict(cls, data: dict) -> "CheckResult":
return cls(**data)
@dataclass(frozen=True)
class RuleResult:
"""
Result of evaluating a CancellationRule.
A rule can consist out of multiple different checks, each partial_result is recorded individually.
A RuleResult encodes both the feasibility of a cancellation via `cancellation_possible` and
the resulting consequences in form of fees which can be expressed as:
- absolute position fees of a fixed amount
- relative position fees of a percentage of the position price
- minimum process fees, the total cancellation fee across all positions and the process must be at least this
- additional process fee, an additional processing fee is charged in addition to the per position fees
"""
id: int
partial_results: List[CheckResult]
fee_type: FeeType
fee: Decimal
type: Literal['rule'] = field(default="rule")
@classmethod
def from_dict(cls, data: dict) -> "RuleResult":
return cls(
id=data["id"],
partial_results=[CheckResult.from_dict(r) for r in data["partial_results"]],
fee_type=FeeType(data["fee_type"]),
fee=Decimal(data["fee"]),
)
@property
def cancellation_possible(self) -> bool:
return all(result.cancellation_possible for result in self.partial_results)
@classmethod
def from_absolute_fee(
cls,
id: int,
partial_results: List[CheckResult],
fee_type: Literal[FeeType.POSITION],
absolute_fee: Decimal
) -> "RuleResult":
return RuleResult(id=id, partial_results=partial_results, fee_type=fee_type, fee=absolute_fee)
@classmethod
def from_relative_fee(
cls,
id: int,
partial_results: List[CheckResult],
fee_type: Literal[FeeType.POSITION],
position_price: Decimal,
percentage: Decimal,
currency: str
) -> "RuleResult":
return RuleResult(id=id, partial_results=partial_results, fee_type=fee_type,
fee=round_decimal(position_price * (percentage / 100), currency))
@classmethod
def from_process_fee(
cls,
id: int,
partial_results: List[CheckResult],
fee_type: Literal[FeeType.MINIMUM, FeeType.ADDITIONAL],
absolute_fee: Decimal,
reference_price: Decimal
) -> "RuleResult":
if fee_type == FeeType.MINIMUM:
if reference_price < absolute_fee:
fee = absolute_fee - reference_price
else:
fee = Decimal(0)
elif fee_type == FeeType.ADDITIONAL:
fee = absolute_fee
else:
raise ValueError("Unknown fee type")
return RuleResult(id=id, partial_results=partial_results, fee_type=fee_type, fee=fee)
def __lt__(self, other: object) -> bool:
if not isinstance(other, RuleResult):
return NotImplemented
if self.cancellation_possible == other.cancellation_possible:
return self.fee < other.fee
else:
return self.cancellation_possible and not other.cancellation_possible
@dataclass(frozen=True)
class Checks:
position: List["CancellationCheck"]
process: List["CancellationCheck"]
@property
def prefetches(self) -> List[Callable[[], Prefetch]]:
return list(chain.from_iterable(
check.prefetches for check in [*self.position, *self.process]
))
@property
def related_selects(self) -> List[str]:
return list(chain.from_iterable(
check.related_selects for check in [*self.position, *self.process]
))
PositionSet: TypeAlias = Set[OrderPosition]
class PositionCheckFn(Protocol):
def __call__(self, order: Order, keep: PositionSet, position: OrderPosition, check_ts: datetime.datetime,
/) -> Optional[CheckResult]:
...
class ProcessCheckFn(Protocol):
def __call__(self, order: Order, keep: PositionSet, check_ts: datetime.datetime, /) -> Optional[CheckResult]:
...
@dataclass(frozen=True)
class CancellationCheck:
id: str
type: CheckTypes
check_fn: PositionCheckFn | ProcessCheckFn = field(compare=False)
prefetches: List[Callable[[], Prefetch]] = field(default_factory=list)
related_selects: List[str] = field(default_factory=list)
def evaluate(self, order: Order, keep: PositionSet,
position: OrderPosition | None, check_ts: datetime.datetime) -> Optional[CheckResult]:
if position and self.type == CheckTypes.POSITION:
return self.check_fn(order, keep, position, check_ts)
elif position is None and self.type == CheckTypes.PROCESS:
return self.check_fn(order, keep, check_ts)
else:
raise ValidationError("Type of the rule doesn't match the check_fn")
@dataclass(frozen=True)
class PositionResult:
position_check_results: Dict[int, List[CheckResult]]
position_rule_results: Dict[int, List[RuleResult]]
@classmethod
def from_dict(cls, data: dict) -> "PositionResult":
return cls(
position_check_results={
int(pos_id): [CheckResult.from_dict(r) for r in results]
for pos_id, results in data["position_check_results"].items()
},
position_rule_results={
int(pos_id): [RuleResult.from_dict(r) for r in results]
for pos_id, results in data["position_rule_results"].items()
},
)
@property
def cancellation_possible(self) -> bool:
def ok(results: List[CheckResult] | List[RuleResult]) -> bool:
return all([val.cancellation_possible for val in results]) if results else True
return all(
ok(results)
for d in
(self.position_check_results,
{key: [min(pos_res)] for key, pos_res in self.position_rule_results.items() if pos_res})
for results in d.values()
)
@property
def fee_value(self) -> Decimal:
fee_value = Decimal("0.00")
for pos_id, results in self.position_rule_results.items():
if len(results) > 0:
best_option = min(results)
if best_option.cancellation_possible:
fee_value += best_option.fee
return fee_value
@dataclass(frozen=True)
class ProcessResult:
process_check_results: List[CheckResult]
process_rule_results: List[RuleResult]
@classmethod
def from_dict(cls, data: dict) -> "ProcessResult":
return cls(
process_check_results=[CheckResult.from_dict(r) for r in data["process_check_results"]],
process_rule_results=[RuleResult.from_dict(r) for r in data["process_rule_results"]],
)
@property
def cancellation_possible(self) -> bool:
results: List[CheckResult | RuleResult] = [*self.process_check_results]
if self.process_rule_results:
results.append(min(self.process_rule_results))
return all(res.cancellation_possible for res in results)
@property
def fee_value(self) -> Decimal:
if not self.process_rule_results:
return Decimal("0.00")
best_option = min(self.process_rule_results)
if best_option.cancellation_possible:
return best_option.fee
return Decimal("0.00")
@dataclass(frozen=True)
class CancellationResult:
position_result: PositionResult
process_result: ProcessResult
@classmethod
def from_dict(cls, data: dict) -> "CancellationResult":
return cls(
position_result=PositionResult.from_dict(data["position_result"]),
process_result=ProcessResult.from_dict(data["process_result"]),
)
@property
def cancellation_possible(self) -> bool:
return self.position_result.cancellation_possible and self.process_result.cancellation_possible
class Cancellation(models.Model):
CREATED: Final = "CREATED"
APPROVAL_PENDING: Final = "APPROVAL_PENDING"
PERFORMED: Final = "PERFORMED"
CANCELLED: Final = "CANCELLED"
CANCELLATION_STATE = (
(CREATED, _("Created")),
(APPROVAL_PENDING, _("Approval pending")),
(PERFORMED, _("Performed")),
(CANCELLED, _("Cancelled")),
)
event = models.ForeignKey(
Event,
verbose_name=_("Event"),
related_name="cancellations",
on_delete=models.CASCADE
)
order = models.ForeignKey(
Order,
verbose_name=_("Order"),
related_name="cancellations",
on_delete=models.CASCADE
)
keep = models.ManyToManyField(
to=OrderPosition,
verbose_name=_("Positions to keep"),
)
evaluation_ts = models.DateTimeField(
verbose_name=_("Cancellation datetime"),
auto_now_add=True,
)
state = models.CharField(
max_length=16,
choices=CANCELLATION_STATE,
default=CREATED,
verbose_name=_("State of the cancellation"),
)
_result = models.JSONField(default=dict, db_column="result", encoder=DjangoJSONEncoder)
@property
def result(self) -> CancellationResult:
return CancellationResult.from_dict(self._result)
@result.setter
def result(self, value: CancellationResult):
if not isinstance(value, CancellationResult):
raise TypeError("result must be a CancellationResult instance")
if self._result:
raise ValueError("result is write-once and has already been set")
self._result = asdict(value)
@property
def possible(self) -> bool:
return self.result.cancellation_possible
@staticmethod
def evaluate(event: Event, order: Order, keep: Set[OrderPosition],
check_ts: datetime.datetime) -> "CancellationResult":
# validate that all keep order positions are part of the order
for p in keep:
if p.order_id != order.id:
raise ValidationError("OrderPosition {} does not belong to order {}".format(p.code, order.code))
# exclude canceled positions
for p in order.positions.all():
if p.canceled:
keep.add(p)
# collect all checks, position_rules and process_rules that are applicable
checks = CancellationRule.collect_checks(event=event)
position_rules: QuerySet[PositionCancellationRule] = PositionCancellationRule.objects.filter(
event=event).with_rule_data().all()
process_rules: QuerySet[ProcessCancellationRule] = ProcessCancellationRule.objects.filter(
event=event).with_rule_data().all()
order = CancellationRule.prefetch_order(event, order, checks)
# keep track of all decisions so we can explain them in the logs
position_check_results: Dict[int, List[CheckResult]] = {}
position_rule_results: Dict[int, List[RuleResult]] = {}
# perform all position checks and position rules
for position in order.positions.all():
position_check_results[position.id] = []
position_rule_results[position.id] = []
# skip this position if customer doesn't want to cancel
if position in keep:
continue
# evaluate the system/plugin checks for the position
for check in checks.position:
res = check.evaluate(order=order, keep=keep, position=position, check_ts=check_ts)
if res is not None:
position_check_results[position.id].append(res)
# evaluate all customer specified rules for this position
for rule in position_rules:
result = rule.evaluate_position_rule(order, keep, position, check_ts)
if result is not None:
position_rule_results[position.id].append(result)
position_results = PositionResult(position_check_results=position_check_results,
position_rule_results=position_rule_results)
# we need the current fee_value to select the cheapest process rule
temp_position_fees = position_results.fee_value
# again keep track of all decisions so we can explain them in the logs
process_check_results: List[CheckResult] = []
process_rule_results: List[RuleResult] = []
# evaluate all system/plugin provided checks for the cancellation process
for check in checks.process:
res = check.evaluate(order=order, keep=keep, position=None, check_ts=check_ts)
if res is not None:
process_check_results.append(res)
# evaluate all customer specified rules for the cancellation process
for rule in process_rules:
result = rule.evaluate_process_rule(order, keep, temp_position_fees, check_ts)
if result is not None:
process_rule_results.append(result)
process_result = ProcessResult(process_check_results=process_check_results,
process_rule_results=process_rule_results)
res = CancellationResult(position_result=position_results, process_result=process_result)
return res
@staticmethod
def prepare(event: Event, order: Order, keep: Set[OrderPosition],
check_ts: datetime.datetime) -> "Cancellation":
res = Cancellation.evaluate(event=event, order=order, keep=set(), check_ts=check_ts)
c = Cancellation(event=event, order=order, result=res, evaluation_ts=check_ts)
c.save()
c.keep.add(*keep)
return c
def execute(self):
# TODO load the cancellation verdict from the id and perform the actions
pass
def _send_self_service_cancellation_checks(event: Event) -> List[Tuple[Any, Any]]:
return self_service_cancellation_checks.send(sender=event)
class CancellationRuleQuerySet(models.QuerySet):
def with_rule_data(self):
model = self.model
qs = self.prefetch_related(*[p() for p in model.rule_prefetches])
if model.rule_related_selects:
qs = qs.select_related(*model.rule_related_selects)
return qs
class CancellationRuleManager(models.Manager.from_queryset(CancellationRuleQuerySet)):
check_type: ClassVar[CheckTypes]
def get_queryset(self):
return super().get_queryset().filter(type=self.check_type).order_by("pk")
class CancellationRule(models.Model):
EARLIEST: Final = "EARLIEST"
LATEST: Final = "LATEST"
SUBEVENT_VARIANT_CHOICES = (
(EARLIEST, _("Earliest")),
(LATEST, _("Latest")),
)
event = models.ForeignKey(
Event,
verbose_name=_("Event"),
related_name="cancellation_rules",
on_delete=models.CASCADE
)
type = models.CharField(
verbose_name=_("Type of the cancellation rule"),
default=CheckTypes.POSITION,
choices=CheckTypes,
max_length=15,
)
allowed_until = ModelRelativeDateTimeField(null=True, blank=True, verbose_name=_("Allowed until"))
except_after = ModelRelativeDateTimeField(null=True, blank=True, verbose_name=_("Except after"))
if TYPE_CHECKING:
allowed_until: Optional[RelativeDateWrapper]
except_after: Optional[RelativeDateWrapper]
# --- position-only fields ---
fee_percentage_per_position = models.DecimalField(
max_digits=5,
decimal_places=2,
validators=[MinValueValidator(Decimal("0.00")), MaxValueValidator(Decimal("100.00"))],
verbose_name=_("Fee Percentage per OrderPosition"),
default=Decimal("0.00"),
)
fee_absolute_per_position = models.DecimalField(
max_digits=13,
decimal_places=2,
verbose_name=_("Absolute fee per OrderPosition"),
default=Decimal("0.00"),
validators=[MinValueValidator(Decimal("0.00"))],
)
all_products = models.BooleanField(
verbose_name=_("All products and variations"),
default=True,
)
limit_products = models.ManyToManyField(Item, verbose_name=_("Products"), blank=True)
limit_variations = models.ManyToManyField(
ItemVariation, blank=True, verbose_name=_("Variations")
)
# --- process-only fields ---
subevent_variant = models.CharField(
max_length=8,
choices=SUBEVENT_VARIANT_CHOICES,
default=EARLIEST,
verbose_name=_("Subevent variant"),
help_text=_("An order can contain tickets for multiple different events if the event has "
"subevents enabled. This choice controls if the order position for the earliest "
"or the latest point in time in the order is used to determine the allowed until and "
"except after dates.")
)
fee_cancellation_process = models.DecimalField(
max_digits=13,
decimal_places=2,
verbose_name=_("Absolute fee per Cancellation"),
default=Decimal("0.00"),
validators=[MinValueValidator(Decimal("0.00"))],
)
fee_mode = models.CharField(
verbose_name=_("The method with which process and position fees are combined."),
choices=[
(FeeType.MINIMUM, FeeType.MINIMUM.label),
(FeeType.ADDITIONAL, FeeType.ADDITIONAL.label),
],
blank=True,
null=True,
max_length=15,
)
class Meta:
constraints = [
models.CheckConstraint(
condition=models.Q(type__in=[CheckTypes.POSITION, CheckTypes.PROCESS]),
name="cancellation_rule_type_valid",
),
]
@staticmethod
def collect_checks(event: Event, send_fn: Callable[
[Event], List[Tuple[Any, Any]]
] = _send_self_service_cancellation_checks) -> Checks:
position_checks: List[CancellationCheck] = []
process_checks: List[CancellationCheck] = []
seen = set()
for recv, resp in send_fn(event):
if resp is None:
continue
if not isinstance(resp, CancellationCheck):
raise ValueError('self_service_cancellation_checks received response of wrong type')
if resp.id in seen:
raise ValueError('self_service_cancellation_checks received multiple responses with the id')
seen.add(resp.id)
if resp.type == CheckTypes.POSITION:
position_checks.append(resp)
if resp.type == CheckTypes.PROCESS:
process_checks.append(resp)
return Checks(position=position_checks, process=process_checks)
@staticmethod
def prefetch_order(event: Event, order: Order, checks: Checks) -> Order:
prefetches = [pref() for pref in [*checks.prefetches,
*PositionCancellationRule.prefetches,
*ProcessCancellationRule.prefetches]]
related_selects = {*checks.related_selects,
*PositionCancellationRule.related_selects,
*ProcessCancellationRule.related_selects}
qs = Order.objects.prefetch_related(*prefetches)
if related_selects:
qs = qs.select_related(*related_selects)
return qs.get(event=event, id=order.id)
@staticmethod
def _resolve_date_field_common(
date_field: RelativeDateWrapper,
order: Order,
resolve_subevent: Callable[[Any], Any],
) -> datetime.date | datetime.datetime:
reldate_type = date_field.choice
if reldate_type == "date":
return make_aware(
datetime.datetime.combine(date_field.date(order.event), datetime.time(hour=23, minute=59, second=59)),
order.event.timezone,
)
elif reldate_type == "datetime":
return date_field.datetime(order.event)
if reldate_type.base == "order":
return date_field.datetime(order)
if not order.event.has_subevents:
return date_field.datetime(order.event)
return date_field.datetime(resolve_subevent(reldate_type))
def clean(self):
super().clean()
errors = {}
if self.type == CheckTypes.PROCESS:
if self.fee_mode not in (FeeType.MINIMUM, FeeType.ADDITIONAL):
errors["fee_mode"] = _(
"Fee mode is not valid on a process rule."
)
if self.fee_percentage_per_position or self.fee_absolute_per_position:
errors["fee_percentage_per_position"] = _(
"Position fees must be unset on a process rule."
)
if self.pk and (self.limit_products.exists() or self.limit_variations.exists()):
errors["limit_products"] = _(
"Product/variation limits are not valid on a process rule."
)
if self.type == CheckTypes.POSITION:
if self.fee_cancellation_process:
errors["fee_cancellation_process"] = _(
"Process fee must be unset on a position rule."
)
if self.fee_mode:
errors["fee_mode"] = _(
"Fee mode is not valid on a position rule."
)
if errors:
raise ValidationError(errors)
class PositionCancellationRuleManager(CancellationRuleManager):
check_type = CheckTypes.POSITION
class PositionCancellationRule(CancellationRule):
"""
PositionCancellationRules answer the questions:
- Can this position be canceled?
- What is the price for cancelling this position?
"""
objects = PositionCancellationRuleManager()
rule_prefetches: ClassVar[List[Callable[[], Prefetch]]] = [
lambda: Prefetch('limit_products'),
lambda: Prefetch('limit_variations'),
]
rule_related_selects: ClassVar[List[str]] = []
prefetches: ClassVar[List[Callable[[], Prefetch]]] = [
lambda: Prefetch('all_positions__item'),
lambda: Prefetch('event'),
]
related_selects: ClassVar[List[str]] = []
class Meta:
proxy = True
def save(self, *args, **kwargs):
self.type = CheckTypes.POSITION
self.full_clean()
super().save(*args, **kwargs)
def _position_matches_rule(self, position: OrderPosition) -> Optional[CheckResult]:
with ensure_no_queries():
res = CheckResult(
id=f"position_rule_{self.id}",
reason=_("Rule matches this product"),
cancellation_possible=True
)
if self.all_products:
return res
item_pks = {item.pk for item in self.limit_products.all()}
if position.item_id in item_pks:
return res
variation_pks = {variation.pk for variation in self.limit_variations.all()}
if position.variation_id in variation_pks:
return res
return None
@staticmethod
def _resolve_date_field(date_field: RelativeDateWrapper, order: Order,
position: OrderPosition) -> datetime.date | datetime.datetime:
return CancellationRule._resolve_date_field_common(
date_field, order, resolve_subevent=lambda _reldate_type: position.subevent
)
def _evaluate_cancellation_moment(self, position: OrderPosition, check_ts: datetime.datetime) -> List[CheckResult]:
check_results = []
order = position.order
for param in ('allowed_until', 'except_after'):
value: RelativeDateWrapper | None = getattr(self, param, None)
if value is not None:
if check_ts <= self._resolve_date_field(value, order, position):
check_results.append(
CheckResult(
id=f"position_rule_{self.id}_{param}",
reason=_("{} is earlier than {} cutoff {}".format(check_ts, param, value)),
cancellation_possible=True
)
)
else:
check_results.append(
CheckResult(
id=f"position_rule_{self.id}_{param}",
reason=_("{} is later than {} cutoff {}".format(check_ts, param, value)),
cancellation_possible=False
)
)
else:
check_results.append(
CheckResult(
id=f"position_rule_{self.id}_{param}",
reason=_("No {} limit defined".format(param)),
cancellation_possible=True
)
)
return check_results
def evaluate_position_rule(self, order: Order, _keep: Set[OrderPosition], position: OrderPosition,
check_ts: datetime.datetime) -> Optional[RuleResult]:
rule_check_results = []
match = self._position_matches_rule(position)
if match:
rule_check_results.append(match)
rule_check_results.extend(self._evaluate_cancellation_moment(position, check_ts))
if self.fee_percentage_per_position and self.fee_absolute_per_position:
raise NotImplementedError(
"Combination of fee_percentage_per position and fee_absolute_per_position is not valid")
elif self.fee_absolute_per_position != Decimal(0.00):
return RuleResult.from_absolute_fee(
id=self.id,
partial_results=rule_check_results,
fee_type=FeeType.POSITION,
absolute_fee=self.fee_absolute_per_position
)
else:
return RuleResult.from_relative_fee(
id=self.id,
partial_results=rule_check_results,
fee_type=FeeType.POSITION,
position_price=position.price,
percentage=self.fee_percentage_per_position,
currency=order.event.currency
)
class ProcessCancellationRuleManager(CancellationRuleManager):
check_type = CheckTypes.PROCESS
class ProcessCancellationRule(CancellationRule):
"""
ProcessCancellationRules answer the question:
- What is the processing fee for performing this cancellation?
"""
objects = ProcessCancellationRuleManager()
rule_prefetches: ClassVar[List[Callable[[], Prefetch]]] = []
rule_related_selects: ClassVar[List[str]] = []
prefetches: ClassVar[List[Callable[[], Prefetch]]] = [
lambda: Prefetch('event'),
]
related_selects: ClassVar[List[str]] = []
class Meta:
proxy = True
def save(self, *args, **kwargs):
self.type = CheckTypes.PROCESS
self.full_clean()
super().save(*args, **kwargs)
@staticmethod
def _resolve_date_field(date_field: RelativeDateWrapper, order: Order,
mode: Literal["EARLIEST", "LATEST"] | str) -> datetime.date | datetime.datetime:
if mode not in ('EARLIEST', 'LATEST'):
raise ValidationError('Mode is invalid')
comparators = {
"EARLIEST": operator.lt,
"LATEST": operator.gt,
}
compare = comparators[mode]
def resolve_subevent(reldate_type):
base_event = order.event
base_value: None | datetime.date = None
for pos in order.positions.all():
e = pos.subevent if pos.subevent else pos.event
value = getattr(e, reldate_type.attribute)
if value is None:
continue # skip when there is no value
if base_value is None or compare(value, base_value):
base_event = e
base_value = value
return base_event
return CancellationRule._resolve_date_field_common(date_field, order, resolve_subevent)
def _evaluate_cancellation_moment(self, order: Order, check_ts: datetime.datetime) -> List[CheckResult]:
check_results: List[CheckResult] = []
for param in ('allowed_until', 'except_after'):
value: RelativeDateWrapper | None = getattr(self, param, None)
if value is not None:
if check_ts <= self._resolve_date_field(value, order, self.subevent_variant):
check_results.append(
CheckResult(
id=f"process_rule_{self.id}_{param}",
reason=_("{} is earlier than {} cutoff {}".format(check_ts, param, value)),
cancellation_possible=True
)
)
else:
check_results.append(
CheckResult(
id=f"process_rule_{self.id}_{param}",
reason=_("{} is later than {} cutoff {}".format(check_ts, param, value)),
cancellation_possible=False
)
)
else:
check_results.append(
CheckResult(
id=f"process_rule_{self.id}_{param}",
reason=_("No {} limit defined".format(param)),
cancellation_possible=True
)
)
return check_results
def evaluate_process_rule(self, order: Order, _keep: Set[OrderPosition], position_fees: Decimal,
check_ts: datetime.datetime) -> Optional[RuleResult]:
fee_mode = self.fee_mode
if fee_mode not in (FeeType.MINIMUM, FeeType.ADDITIONAL):
raise ValueError(f"Unexpected fee_mode: {fee_mode!r}")
check_results: List[CheckResult] = self._evaluate_cancellation_moment(order, check_ts)
return RuleResult.from_process_fee(
id=self.id,
partial_results=check_results,
fee_type=fee_mode,
absolute_fee=self.fee_cancellation_process,
reference_price=position_fees,
)
-1
View File
@@ -166,7 +166,6 @@ class Device(LoggedModel):
)
security_profile = models.CharField(
max_length=190,
verbose_name=_('Security profile'),
default='full',
null=True,
blank=False
+4 -2
View File
@@ -1050,8 +1050,10 @@ class Item(LoggedModel):
replace_year = valid_until.year
replace_month = valid_until.month + self.validity_dynamic_duration_months
replace_year += (replace_month - 1) // 12
replace_month = ((replace_month - 1) % 12) + 1
while replace_month > 12:
replace_month -= 12
replace_year += 1
max_day = calendar.monthrange(replace_year, replace_month)[1]
replace_date = date(
year=replace_year,
+45 -37
View File
@@ -626,14 +626,47 @@ class Order(LockModel, LoggedModel):
self.save(update_fields=['last_modified'])
def set_expires(self, now_dt=None, subevents=None):
from pretix.base.services.payment import compute_payment_deadline
now_dt = now_dt or now()
tz = ZoneInfo(self.event.settings.timezone)
self.expires = compute_payment_deadline(
event=self.event,
sales_channel=self.sales_channel,
now_dt=now_dt,
subevents=subevents,
)
sales_channel_suffix = "_" + self.sales_channel.identifier.replace(".", "_")
if not (mode := self.event.settings.get(f'payment_term_mode{sales_channel_suffix}')):
mode = self.event.settings.get('payment_term_mode')
sales_channel_suffix = ""
if mode == 'days':
exp_by_date = now_dt.astimezone(tz) + timedelta(days=self.event.settings.get(f'payment_term_days{sales_channel_suffix}', as_type=int))
exp_by_date = exp_by_date.astimezone(tz).replace(hour=23, minute=59, second=59, microsecond=0)
if self.event.settings.get('payment_term_weekdays'):
if exp_by_date.weekday() == 5:
exp_by_date += timedelta(days=2)
elif exp_by_date.weekday() == 6:
exp_by_date += timedelta(days=1)
elif mode == 'minutes':
exp_by_date = now_dt.astimezone(tz) + timedelta(minutes=self.event.settings.get(f'payment_term_minutes{sales_channel_suffix}', as_type=int))
else:
raise ValueError("'payment_term_mode' has an invalid value '{}'.".format(mode))
self.expires = exp_by_date
term_last = self.event.settings.get('payment_term_last', as_type=RelativeDateWrapper)
if term_last:
if self.event.has_subevents and subevents:
terms = [
term_last.datetime(se).date()
for se in subevents
]
if not terms:
return
term_last = min(terms)
else:
term_last = term_last.datetime(self.event).date()
term_last = make_aware(datetime.combine(
term_last,
time(hour=23, minute=59, second=59)
), tz)
if term_last < self.expires:
self.expires = term_last
@cached_property
def tax_total(self):
@@ -644,6 +677,7 @@ class Order(LockModel, LoggedModel):
return self.total - self.tax_total
def cancel_allowed(self):
# TODO turn into check after replacing cancellation machinery
return (
self.status in (Order.STATUS_PENDING, Order.STATUS_PAID, Order.STATUS_EXPIRED) and self.count_positions
)
@@ -753,36 +787,10 @@ class Order(LockModel, LoggedModel):
"""
Returns whether or not this order can be canceled by the user.
"""
from .checkin import Checkin
if self.cancellation_requests.exists() or not self.cancel_allowed():
return False
positions = list(
self.positions.all().annotate(
has_checkin=Exists(Checkin.objects.filter(position_id=OuterRef('pk'), list__consider_tickets_used=True))
).select_related('item').prefetch_related('issued_gift_cards')
)
cancelable = all([op.item.allow_cancel and not op.has_checkin and not op.blocked for op in positions])
if not cancelable or not positions:
return False
for op in positions:
for gc in op.issued_gift_cards.all():
if gc.value != op.price:
return False
if op.granted_memberships.with_usages().filter(usages__gt=0):
return False
if self.user_cancel_deadline and time_machine_now() > self.user_cancel_deadline:
return False
if self.status == Order.STATUS_PAID:
if self.total == Decimal('0.00'):
return self.event.settings.cancel_allow_user
return self.event.settings.cancel_allow_user_paid
elif self.payment_refund_sum > Decimal('0.00'):
return False
elif self.status == Order.STATUS_PENDING:
return self.event.settings.cancel_allow_user
return False
from pretix.base.models.cancellation import Cancellation
res = Cancellation.evaluate(event=self.event, order=self, keep=set(),
check_ts=datetime.now(tz=ZoneInfo(self.event.settings.timezone)))
return res.cancellation_possible
def propose_auto_refunds(self, amount: Decimal, payments: list=None):
# Algorithm to choose which payments are to be refunded to create the least hassle
+35 -41
View File
@@ -801,18 +801,6 @@ def generate_compressed_addon_list(op, order, event, only_checked_in=False):
return addonlist
def get_sizebox(page: pypdf.PageObject):
mediabox = page.mediabox
cropbox = page.cropbox
return pypdf.generic.RectangleObject((
max(mediabox[0], cropbox[0]),
max(mediabox[1], cropbox[1]),
min(mediabox[2], cropbox[2]),
min(mediabox[3], cropbox[3]),
))
class Renderer:
def __init__(self, event, layout, background_file):
@@ -1091,7 +1079,7 @@ class Renderer:
fontsize = float(o['fontsize'])
height = float(o['height']) * mm
width = float(o['width']) * mm
for _i in range(25): # try adapting the font size at most 25 times
while True:
p, ad, lineheight = self._text_paragraph(op, order, o, override_fontsize=fontsize)
w, h = p.wrapOn(canvas, width, 1000 * mm)
widths = p.getActualLineWidths0()
@@ -1165,10 +1153,11 @@ class Renderer:
elif o['type'] == "poweredby":
self._draw_poweredby(canvas, op, o)
if self.bg_pdf:
first_page = self.bg_pdf.pages[0]
sizebox = get_sizebox(first_page)
page_size = (sizebox.width, sizebox.height)
if first_page.rotation in (90, 270):
page_size = (
self.bg_pdf.pages[0].mediabox[2] - self.bg_pdf.pages[0].mediabox[0],
self.bg_pdf.pages[0].mediabox[3] - self.bg_pdf.pages[0].mediabox[1]
)
if self.bg_pdf.pages[0].get('/Rotate') in (90, 270):
# swap dimensions due to pdf being rotated
page_size = page_size[::-1]
canvas.setPageSize(page_size)
@@ -1243,7 +1232,9 @@ class Renderer:
for i, page in enumerate(fg_pdf.pages):
bg_page = self.bg_pdf.pages[i]
_merge_with_correct_page_media_box(output, page, bg_page)
_correct_page_media_box(bg_page)
page.merge_page(bg_page, over=False)
output.add_page(page)
# pdf_header is a string like "%pdf-X.X"
if float(self.bg_pdf.pdf_header[5:]) > float(fg_pdf.pdf_header[5:]):
@@ -1308,36 +1299,39 @@ def merge_background(fg_pdf: PdfWriter, bg_pdf: PdfWriter, out_file, compress):
bg_pdf.write(bg_filename)
subprocess.run(pdftk_cmd, check=True, stdout=out_file)
else:
output = PdfWriter()
for i, page in enumerate(fg_pdf.pages):
bg_page = bg_pdf.pages[i]
_merge_with_correct_page_media_box(output, page, bg_page)
_correct_page_media_box(bg_page)
page.merge_page(bg_page, over=False)
# pdf_header is a string like "%pdf-X.X"
output.pdf_header = (
bg_pdf.pdf_header
if float(bg_pdf.pdf_header[5:]) > float(fg_pdf.pdf_header[5:])
else fg_pdf.pdf_header
)
output.write(out_file)
if float(bg_pdf.pdf_header[5:]) > float(fg_pdf.pdf_header[5:]):
fg_pdf.pdf_header = bg_pdf.pdf_header
fg_pdf.write(out_file)
def _merge_with_correct_page_media_box(output: pypdf.PdfWriter, fg_page: pypdf.PageObject, bg_page: pypdf.PageObject):
"""
Adds fg_page to output, merging bg_page behind it.
If bg_page has a non-zero mergebox/cropbox or is rotated via /Rotate, a transformation is applied to fix this."""
def _correct_page_media_box(page: pypdf.PageObject):
if page.rotation != 0:
page.transfer_rotation_to_content()
media_box = page.mediabox
trsf = pypdf.Transformation()
if bg_page.rotation != 0:
trsf = trsf.rotate(-bg_page.rotation)
mb = get_sizebox(bg_page)
pt1 = trsf.apply_on(mb.lower_left)
pt2 = trsf.apply_on(mb.upper_right)
trsf = trsf.translate(-min(pt1[0], pt2[0]), -min(pt1[1], pt2[1]))
fg_page = output.add_page(fg_page)
fg_page.merge_transformed_page(bg_page, trsf, over=False, expand=False)
if media_box.bottom != 0:
trsf = trsf.translate(0, -media_box.bottom)
if media_box.left != 0:
trsf = trsf.translate(-media_box.left, 0)
page.add_transformation(trsf, False)
for b in ["/MediaBox", "/CropBox", "/BleedBox", "/TrimBox", "/ArtBox"]:
if b in page:
rr = pypdf.generic.RectangleObject(page[b])
pt1 = trsf.apply_on(rr.lower_left)
pt2 = trsf.apply_on(rr.upper_right)
page[pypdf.generic.NameObject(b)] = pypdf.generic.RectangleObject((
min(pt1[0], pt2[0]),
min(pt1[1], pt2[1]),
max(pt1[0], pt2[0]),
max(pt1[1], pt2[1]),
))
@deconstructible
+16 -7
View File
@@ -111,21 +111,21 @@ class RelativeDate:
base_date_name: str = 'event__date_from__'
def __post_init__(self) -> None:
if self.is_after and not self._choice.supports_after:
if self.is_after and not self.choice.supports_after:
raise ValueError(
"The selected base date and attribute combination does not support relative dates placed after the base date"
)
if not self.is_after and not self._choice.supports_before:
if not self.is_after and not self.choice.supports_before:
raise ValueError(
"The selected base date and attribute combination does not support relative dates placed before the base date")
@property
def _choice(self):
def choice(self):
return BaseChoice.find(BASE_CHOICES, self.base_date_name)
@property
def key(self):
return self._choice.key
return self.choice.key
def __eq__(self, o: object) -> bool:
if not isinstance(o, RelativeDate):
@@ -141,7 +141,7 @@ class RelativeDate:
"""
from .models import Event, Order, SubEvent
choice = self._choice
choice = self.choice
if choice.base == "order" and isinstance(base, Order):
event = base.event
@@ -210,13 +210,13 @@ class RelativeDate:
if self.minutes is not None:
return 'RELDATE/minutes/{}/{}/{}'.format( #
self.minutes,
self._choice.key,
self.choice.key,
'after' if self.is_after else '',
)
return 'RELDATE/{}/{}/{}/{}'.format( #
self.days,
self.time.strftime('%H:%M:%S') if self.time else '-',
self._choice.key,
self.choice.key,
'after' if self.is_after else '',
)
@@ -270,6 +270,15 @@ class RelativeDateWrapper:
def __init__(self, data: Union[datetime.datetime, RelativeDate]):
self.data = data
@property
def choice(self) -> Literal["datetime", "date"] | BaseChoice:
if isinstance(self.data, datetime.datetime):
return "datetime"
elif isinstance(self.data, datetime.date):
return "date"
else:
return self.data.choice
def date(self, base: "Event | Order | SubEvent") -> datetime.date:
"""
If the RelativeDateWrapper wraps a RelativeDate object:
-1
View File
@@ -1605,7 +1605,6 @@ def add_payment_to_cart_session(cart_session, provider, min_value: Decimal=None,
'max_value': str(max_value) if max_value is not None else None,
'info_data': info_data or {},
})
cart_session['payments_postpone'] = False
def add_payment_to_cart(request, provider, min_value: Decimal=None, max_value: Decimal=None, info_data: dict=None):
+3 -5
View File
@@ -54,7 +54,7 @@ from celery.exceptions import MaxRetriesExceededError
from django.conf import settings
from django.core.files.storage import default_storage
from django.core.mail import EmailMultiAlternatives, SafeMIMEMultipart
from django.core.mail.message import SafeMIMEText, utf8_charset_qp
from django.core.mail.message import SafeMIMEText
from django.db import connection, transaction
from django.db.models import Q
from django.dispatch import receiver
@@ -380,8 +380,6 @@ def mail(email: Union[str, Sequence[str]], subject: Union[str, FormattedString],
class CustomEmail(EmailMultiAlternatives):
encoding = utf8_charset_qp
def _create_mime_attachment(self, content, mimetype):
"""
Convert the content, mimetype pair into a MIME attachment object.
@@ -451,9 +449,9 @@ def mail_send_task(self, **kwargs) -> bool:
# Rewrite all <img> tags from real URLs or data URLs to inline attachments referred to by content ID
if outgoing_mail.body_html is not None:
html_message = SafeMIMEMultipart(_subtype='related')
html_message = SafeMIMEMultipart(_subtype='related', encoding=settings.DEFAULT_CHARSET)
html_with_cid, cid_images = replace_images_with_cid_paths(outgoing_mail.body_html)
html_message.attach(SafeMIMEText(html_with_cid, 'html', utf8_charset_qp))
html_message.attach(SafeMIMEText(html_with_cid, 'html', settings.DEFAULT_CHARSET))
attach_cid_images(html_message, cid_images, verify_ssl=True)
email.attach_alternative(html_message, "multipart/related")
+265 -37
View File
@@ -50,8 +50,8 @@ from django.core.cache import cache
from django.core.exceptions import ValidationError
from django.db import models, transaction
from django.db.models import (
Count, Exists, F, IntegerField, Max, Min, OuterRef, Q, QuerySet, Subquery,
Sum, Value,
Count, Exists, F, IntegerField, Max, Min, OuterRef, Prefetch, Q, QuerySet,
Subquery, Sum, Value,
)
from django.db.models.functions import Cast, Greatest
from django.db.transaction import get_connection
@@ -71,6 +71,9 @@ from pretix.base.models import (
Membership, Order, OrderPayment, OrderPosition, Quota, Seat,
SeatCategoryMapping, User, Voucher,
)
from pretix.base.models.cancellation import (
Cancellation, CancellationCheck, CheckResult, CheckTypes, PositionSet,
)
from pretix.base.models.event import Event_SettingsStore, SubEvent
from pretix.base.models.orders import (
BlockedTicketSecret, CheckoutSession, InvoiceAddress, OrderFee,
@@ -103,7 +106,7 @@ from pretix.base.signals import (
order_approved, order_canceled, order_changed, order_denied, order_expired,
order_expiry_changed, order_fee_calculation, order_paid, order_placed,
order_reactivated, order_split, order_valid_if_pending, periodic_task,
validate_order,
self_service_cancellation_checks, validate_order,
)
from pretix.base.timemachine import time_machine_now, time_machine_now_assigned
from pretix.celery_app import app
@@ -961,7 +964,7 @@ def _check_positions(event: Event, now_dt: datetime, time_machine_now_dt: dateti
def _apply_rounding_and_fees(positions: List[CartPosition], payment_requests: List[dict], address: InvoiceAddress,
meta_info: dict, event: Event, sales_channel: SalesChannel, require_approval=False):
meta_info: dict, event: Event, require_approval=False):
fees = []
# Pre-rounding, pre-fee total is used for fee calculation
total = sum([c.gross_price_before_rounding for c in positions])
@@ -1021,14 +1024,7 @@ def _apply_rounding_and_fees(positions: List[CartPosition], payment_requests: Li
payments_assigned += to_pay
p['payment_amount'] = to_pay
allow_postponed_payment = (
require_approval or
(
sales_channel.identifier in event.settings.payment_choice_postpone_allowed_channels and not payment_requests
)
)
if total != payments_assigned and not allow_postponed_payment:
if total != payments_assigned and not require_approval:
raise OrderError(_("The selected payment methods do not cover the total balance."))
return fees
@@ -1050,15 +1046,7 @@ def _create_order(event: Event, *, email: str, positions: List[CartPosition], no
# Final calculation of fees, also performs final rounding
try:
fees = _apply_rounding_and_fees(
positions,
payment_requests,
address,
meta_info,
event,
sales_channel=sales_channel,
require_approval=require_approval
)
fees = _apply_rounding_and_fees(positions, payment_requests, address, meta_info, event, require_approval=require_approval)
except TaxRule.SaleNotAllowed:
raise OrderError(error_messages['country_blocked'])
@@ -1695,7 +1683,8 @@ class OrderChangeManager:
@property
def position(self) -> OrderPosition:
if self._positions is None:
raise RuntimeError("Order position has not been created yet. Call commit() first on OrderChangeManager.")
raise RuntimeError(
"Order position has not been created yet. Call commit() first on OrderChangeManager.")
if len(self._positions) != 1:
raise RuntimeError("More than one position created.")
return self._positions[0]
@@ -1914,7 +1903,8 @@ class OrderChangeManager:
def add_position(self, item: Item, variation: ItemVariation, price: Decimal, addon_to: OrderPosition = None,
subevent: SubEvent = None, seat: Seat = None, membership: Membership = None,
valid_from: datetime = None, valid_until: datetime = None, count: int = 1) -> 'OrderChangeManager.AddPositionResult':
valid_from: datetime = None, valid_until: datetime = None,
count: int = 1) -> 'OrderChangeManager.AddPositionResult':
if count < 1:
raise ValueError("Count must be positive")
if isinstance(seat, str):
@@ -2631,19 +2621,20 @@ class OrderChangeManager:
)
nextposid += 1
new_pos.append(pos)
new_logs.append(self.order.log_action('pretix.event.order.changed.add', user=self.user, auth=self.auth, data={
'position': pos.pk,
'item': op.item.pk,
'variation': op.variation.pk if op.variation else None,
'addon_to': op.addon_to.pk if op.addon_to else None,
'price': op.price.gross,
'positionid': pos.positionid,
'membership': pos.used_membership_id,
'subevent': op.subevent.pk if op.subevent else None,
'seat': op.seat.pk if op.seat else None,
'valid_from': op.valid_from.isoformat() if op.valid_from else None,
'valid_until': op.valid_until.isoformat() if op.valid_until else None,
}, save=False))
new_logs.append(
self.order.log_action('pretix.event.order.changed.add', user=self.user, auth=self.auth, data={
'position': pos.pk,
'item': op.item.pk,
'variation': op.variation.pk if op.variation else None,
'addon_to': op.addon_to.pk if op.addon_to else None,
'price': op.price.gross,
'positionid': pos.positionid,
'membership': pos.used_membership_id,
'subevent': op.subevent.pk if op.subevent else None,
'seat': op.seat.pk if op.seat else None,
'valid_from': op.valid_from.isoformat() if op.valid_from else None,
'valid_until': op.valid_until.isoformat() if op.valid_until else None,
}, save=False))
op.result._positions = new_pos
LogEntry.bulk_create_and_postprocess(new_logs)
@@ -2971,7 +2962,8 @@ class OrderChangeManager:
return total
def _check_order_size(self):
if (len(self.order.positions.all()) + sum([op.count for op in self._operations if isinstance(op, self.AddOperation)])) > settings.PRETIX_MAX_ORDER_SIZE:
if (len(self.order.positions.all()) + sum([op.count for op in self._operations if isinstance(op,
self.AddOperation)])) > settings.PRETIX_MAX_ORDER_SIZE:
raise OrderError(
self.error_messages['max_order_size'] % {
'max': settings.PRETIX_MAX_ORDER_SIZE,
@@ -3606,3 +3598,239 @@ def signal_listener_issue_media(sender: Event, order: Order, **kwargs):
'customer': order.customer_id,
}
)
def position_not_used_cancellation_check(order: Order, keep: PositionSet, position: OrderPosition,
check_ts: datetime):
for pos in order.positions.all():
if pos == position and position not in keep:
for checkin in pos.all_checkins.all():
if checkin.successful and checkin.list.consider_tickets_used:
return CheckResult(
id="pretixbase_position_not_used",
reason=f"Position used in Checkin {checkin}",
cancellation_possible=False,
)
else:
return CheckResult(
id="pretixbase_position_not_used",
reason="Position not up for cancellation",
cancellation_possible=True,
)
return CheckResult(
id="pretixbase_position_not_used",
reason="Ticket not used",
cancellation_possible=True,
)
@receiver(self_service_cancellation_checks, dispatch_uid="pretixbase_position_not_used")
def signal_listener_position_not_used(sender: Event, **kwargs):
return CancellationCheck(id="pretixbase_position_not_used",
type=CheckTypes.POSITION,
check_fn=position_not_used_cancellation_check,
prefetches=[
lambda: Prefetch('all_positions__all_checkins__list', )
])
def position_not_blocked_check(order: Order, keep: PositionSet, position: OrderPosition,
check_ts: datetime):
for pos in order.positions.all():
if pos == position and position not in keep:
return CheckResult(
id="pretixbase_position_not_blocked",
reason="Position is blocked" if pos.blocked else "Position is not blocked",
cancellation_possible=not pos.blocked,
)
return None
@receiver(self_service_cancellation_checks, dispatch_uid="pretixbase_position_not_blocked")
def signal_listener_position_not_blocked(sender: Event, **kwargs):
return CancellationCheck(id="pretixbase_position_not_blocked",
type=CheckTypes.POSITION,
check_fn=position_not_blocked_check,
prefetches=[
lambda: Prefetch('all_positions', )
])
def position_giftcard_not_used(order: Order, keep: PositionSet, position: OrderPosition,
check_ts: datetime):
for pos in order.positions.all():
if pos == position and position not in keep:
if len(pos.issued_gift_cards.all()) > 0:
for gc in pos.issued_gift_cards.all():
if gc.value != pos.price:
return CheckResult(
id="pretixbase_position_giftcard_not_used",
reason="Issued giftcard was used",
cancellation_possible=False,
)
return CheckResult(
id="pretixbase_position_giftcard_not_used",
reason="Issued giftcard was not used",
cancellation_possible=True,
)
return None
@receiver(self_service_cancellation_checks, dispatch_uid="pretixbase_position_giftcard_not_used")
def signal_listener_position_giftcard_not_used(sender: Event, **kwargs):
return CancellationCheck(id="pretixbase_position_giftcard_not_used",
type=CheckTypes.POSITION,
check_fn=position_giftcard_not_used,
prefetches=[
lambda: Prefetch('all_positions__issued_gift_cards', )
])
def position_membership_not_used(order: Order, keep: PositionSet, position: OrderPosition,
check_ts: datetime):
for pos in order.positions.all():
if pos == position and position not in keep:
if len(pos.granted_memberships.all()) > 0:
for membership in pos.granted_memberships.all():
if membership.usages > 0:
return CheckResult(
id="pretixbase_position_membership_not_used",
reason="Membership was already used",
cancellation_possible=False,
)
return CheckResult(
id="pretixbase_position_giftcard_not_used",
reason="Included Membership was not used",
cancellation_possible=True,
)
else:
return CheckResult(
id="pretixbase_position_membership_not_used",
reason="No membership included",
cancellation_possible=True,
)
return None
@receiver(self_service_cancellation_checks, dispatch_uid="pretixbase_position_membership_not_used")
def signal_position_membership_not_used(sender: Event, **kwargs):
return CancellationCheck(id="pretixbase_position_membership_not_used",
type=CheckTypes.POSITION,
check_fn=position_membership_not_used,
prefetches=[
lambda: Prefetch('all_positions__granted_memberships',
queryset=Membership.objects.with_usages(), )
])
def position_item_allow_cancel(order: Order, keep: PositionSet, position: OrderPosition,
check_ts: datetime):
for pos in order.positions.all():
if pos == position and position not in keep:
return CheckResult(
id="pretixbase_position_item_allow_cancel",
reason="Item can be canceled" if pos.item.allow_cancel else "Item cannot be canceled",
cancellation_possible=pos.item.allow_cancel,
)
return None
@receiver(self_service_cancellation_checks, dispatch_uid="pretixbase_position_item_allow_cancel")
def signal_position_item_allow_cancel(sender: Event, **kwargs):
return CancellationCheck(id="pretixbase_position_item_allow_cancel",
type=CheckTypes.POSITION,
check_fn=position_item_allow_cancel,
prefetches=[
lambda: Prefetch('all_positions__item')
])
def process_order_payment_state(order: Order, keep: PositionSet, check_ts: datetime):
if order.status == Order.STATUS_PAID:
if order.total == Decimal("0.00"):
return CheckResult(
id="pretixbase_process_order_paid",
reason="Free orders can be canceled" if order.event.settings.cancel_allow_user else "Free orders cannot be canceled",
cancellation_possible=order.event.settings.cancel_allow_user,
)
return CheckResult(
id="pretixbase_process_order_paid",
reason="Paid orders can be canceled" if order.event.settings.cancel_allow_user_paid else "Paid orders cannot be canceled",
cancellation_possible=order.event.settings.cancel_allow_user_paid,
)
elif order.payment_refund_sum > Decimal('0.00'):
return CheckResult(
id="pretixbase_process_order_paid",
reason="Outstanding refund sum prevents further cancellations",
cancellation_possible=False,
)
elif order.status == Order.STATUS_PENDING:
return CheckResult(
id="pretixbase_process_order_paid",
reason="Pending orders can be canceled" if order.event.settings.cancel_allow_user else "Pending orders cannot be canceled",
cancellation_possible=order.event.settings.cancel_allow_user,
)
else:
return CheckResult(
id="pretixbase_process_order_paid",
reason="Order is in a state that does not allow cancellations",
cancellation_possible=False,
)
@receiver(self_service_cancellation_checks, dispatch_uid="pretixbase_process_order_payment_state")
def signal_listener_process_order_payment_state(sender: Event, **kwargs):
return CancellationCheck(id="pretixbase_process_order_payment_state",
type=CheckTypes.PROCESS,
check_fn=process_order_payment_state,
prefetches=[]
)
def process_cancel_allowed(order: Order, keep: PositionSet, check_ts: datetime):
cancel_allowed = order.cancel_allowed()
return CheckResult(
id="pretixbase_process_cancel_allowed",
reason="Order allows cancellation" if cancel_allowed else "Order doesn't allow for cancellation",
cancellation_possible=cancel_allowed,
)
@receiver(self_service_cancellation_checks, dispatch_uid="pretixbase_process_cancel_allowed")
def signal_listener_process_cancel_allowed(sender: Event, **kwargs):
return CancellationCheck(id="pretixbase_process_process_cancel_allowed",
type=CheckTypes.PROCESS,
check_fn=process_cancel_allowed,
prefetches=[]
)
def process_cancellation_in_progress(order: Order, keep: PositionSet, check_ts: datetime):
if any([c.state not in [Cancellation.PERFORMED, Cancellation.CANCELLED] for c in order.cancellations.all()]):
return CheckResult(
id="pretixbase_process_cancellation_in_progress",
reason="Cancellation request already in progress",
cancellation_possible=False,
)
return CheckResult(
id="pretixbase_process_cancellation_in_progress",
reason="No cancellation request in progress",
cancellation_possible=True,
)
@receiver(self_service_cancellation_checks, dispatch_uid="pretixbase_process_cancellation_in_progress")
def signal_listener_process_cancellation_in_progress(sender: Event, **kwargs):
return CancellationCheck(id="pretixbase_process_process_cancellation_in_progress",
type=CheckTypes.PROCESS,
check_fn=process_cancellation_in_progress,
prefetches=[]
)
# TODO weitere System Checks
# OrderPositions mit Item.min_per_order dürfen nur storniert werden, wenn genug übrig bleiben oder alle des gleichen Items storniert werden
# OrderPositions mit addon_to != None dürfen nur über den bestehenden Add-On-Flow storniert werden
# OrderPositions mit is_bundled dürfen nur mit der Parent-Position zusammen storniert werden
-76
View File
@@ -1,76 +0,0 @@
#
# This file is part of pretix (Community Edition).
#
# Copyright (C) 2014-2020 Raphael Michel and contributors
# Copyright (C) 2020-today pretix GmbH and contributors
#
# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General
# Public License as published by the Free Software Foundation in version 3 of the License.
#
# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are
# applicable granting you additional permissions and placing additional restrictions on your usage of this software.
# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive
# this file, see <https://pretix.eu/about/en/license>.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
# <https://www.gnu.org/licenses/>.
#
from datetime import datetime, time, timedelta
from zoneinfo import ZoneInfo
from django.utils.timezone import make_aware, now
from pretix.base.models import Event, SalesChannel
from pretix.base.reldate import RelativeDateWrapper
def compute_payment_deadline(event: Event, sales_channel: SalesChannel, now_dt=None, subevents=None) -> datetime:
now_dt = now_dt or now()
tz = ZoneInfo(event.settings.timezone)
sales_channel_suffix = "_" + sales_channel.identifier.replace(".", "_")
if not (mode := event.settings.get(f'payment_term_mode{sales_channel_suffix}')):
mode = event.settings.get('payment_term_mode')
sales_channel_suffix = ""
if mode == 'days':
exp_by_date = now_dt.astimezone(tz) + timedelta(
days=event.settings.get(f'payment_term_days{sales_channel_suffix}', as_type=int))
exp_by_date = exp_by_date.astimezone(tz).replace(hour=23, minute=59, second=59, microsecond=0)
if event.settings.get('payment_term_weekdays'):
if exp_by_date.weekday() == 5:
exp_by_date += timedelta(days=2)
elif exp_by_date.weekday() == 6:
exp_by_date += timedelta(days=1)
elif mode == 'minutes':
exp_by_date = now_dt.astimezone(tz) + timedelta(
minutes=event.settings.get(f'payment_term_minutes{sales_channel_suffix}', as_type=int))
else:
raise ValueError("'payment_term_mode' has an invalid value '{}'.".format(mode))
expires = exp_by_date
term_last = event.settings.get('payment_term_last', as_type=RelativeDateWrapper)
if term_last:
if event.has_subevents and subevents:
terms = [
term_last.datetime(se).date()
for se in subevents
]
if not terms:
return expires
term_last = min(terms)
else:
term_last = term_last.datetime(event).date()
term_last = make_aware(datetime.combine(
term_last,
time(hour=23, minute=59, second=59)
), tz)
if term_last < expires:
return term_last
return expires
+2 -68
View File
@@ -343,66 +343,6 @@ def _validate_vat_id_EU(vat_id, country_code):
return vat_id
def _validate_vat_id_EU_fallback_germany(vat_id, country_code, requester_id):
# We can skip most static validation checks because _validate_vat_id_EU always runs before
vat_id = normalize_vat_id(vat_id, country_code)
# The VIES service of the European commission is overused and down due to rate limits A LOT. There is another
# API by German BZSt, but it only works if the requester is German and the requested is not.
# https://www.bzst.de/DE/Unternehmen/Identifikationsnummern/Umsatzsteuer-Identifikationsnummer/AuslaendischeUSt-IdNr/auslaendische_ust_idnr_node.html
try:
r = requests.post(
"https://api.evatr.vies.bzst.de/app/v1/abfrage",
json={
"anfragendeUstid": requester_id,
"angefragteUstid": vat_id,
},
timeout=10,
)
d = r.json()
if r.status_code == 200:
if d['status'] in ('evatr-0000', 'evatr-2008'):
# evatr-0000: Die angefragte Ust-IdNr. ist zum Anfragezeitpunkt gültig.
# evatr-2008: Die angefragte Ust-IdNr. ist zum Anfragezeitpunkt gültig.
# Für die qualifizierte Bestätigungsanfrage liegt einer Besonderheit vor.
# Für Rückfragen wenden Sie sich an das BZSt.
return vat_id
# evatr-2002: Die angefragte USt-IdNr. ist zum Anfragezeitpunkt nicht gültig.
# Sie ist erst gültig ab dem Datum im Feld gueltigAb.
# evatr-2006: Die angefragte Ust-IdNr. ist zum Anfragezeitpunkt nicht gültig.
# Sie war gültig im Zeitraum, der durch die Werte in den Feldern gueltigAb und gueltigBis beschrieben ist.
raise VATIDFinalError(error_messages['invalid'])
elif r.status_code == 400:
if d['status'] in ('evatr-0002', 'evatr-0004', 'evatr-0008'):
# evatr-0002: Mindestens eins der Pflichtfelder ist nicht besetzt.
# evatr-0004: Die anfragende DE Ust-IdNr. ist syntaktisch falsch. Sie passt nicht in das deutsche Erzeugungsschema.
# evatr-0008: Die maximale Anzahl von qualifizierten Bestätigungsabfragen für diese Session wurde erreicht.
# Bitte starten Sie erneut mit einer einfachen Bestätigungsabfrage.
raise VATIDTemporaryError(error_messages['unavailable'])
# evatr-0005: Die angegebene angefragte Ust-IdNr. ist syntaktisch falsch.
# evatr-0012: Die angefrage USt-IdNr. ist syntaktisch falsch. Sie passt nicht in das Erzeugungsschema.
# evatr-2003: Das angegebene Länderkennzeichen der angefragten USt-IdNr. ist nicht gültig.
raise VATIDFinalError(error_messages['invalid'])
elif r.status_code == 403:
# evatr-0006: Die anfragende DE USt-IdNr. ist nicht berechtigt eine DE Ust-IdNr. anzufragen.
# evatr-0007: Fehlerhafter Aufruf.
raise VATIDTemporaryError(error_messages['unavailable'])
elif r.status_code == 404:
if d['status'] in ('evatr-2005'):
# evatr-2005: Die angegebene eigene DE Ust-IdNr. ist zum Anfragezeitpunkt nicht gültig.
raise VATIDTemporaryError(error_messages['unavailable'])
# evatr-2001: Die angefragte USt-IdNr. ist zum Anfragezeitpunkt nicht vergeben.
raise VATIDFinalError(error_messages['invalid'])
else: # 500, 503
raise VATIDTemporaryError(error_messages['unavailable'])
except requests.RequestException:
logger.exception('VAT ID checking failed for country {}'.format(country_code))
raise VATIDTemporaryError(error_messages['unavailable'])
except ValueError: # JSON parsing failed
logger.exception('VAT ID checking failed for country {}'.format(country_code))
raise VATIDTemporaryError(error_messages['unavailable'])
def _validate_vat_id_CH(vat_id, country_code):
if vat_id[:3] != 'CHE':
raise VATIDFinalError(error_messages['country_mismatch'])
@@ -454,18 +394,12 @@ def _validate_vat_id_CH(vat_id, country_code):
return vat_id
def validate_vat_id(vat_id, country_code, requester_id=None):
def validate_vat_id(vat_id, country_code):
if not vat_id:
return vat_id
country_code = str(country_code)
if is_eu_country(country_code):
try:
return _validate_vat_id_EU(vat_id, country_code)
except VATIDTemporaryError:
if requester_id and requester_id.startswith("DE") and not vat_id.startswith("DE"):
return _validate_vat_id_EU_fallback_germany(vat_id, country_code, requester_id)
else:
raise
return _validate_vat_id_EU(vat_id, country_code)
elif country_code == 'CH':
return _validate_vat_id_CH(vat_id, country_code)
elif country_code == 'NO':
File diff suppressed because one or more lines are too long
+10 -22
View File
@@ -50,8 +50,8 @@ from pretix.api.serializers.order import (
from pretix.api.serializers.waitinglist import WaitingListSerializer
from pretix.base.i18n import LazyLocaleException
from pretix.base.models import (
CachedCombinedTicket, CachedTicket, Event, Invoice, InvoiceAddress,
OrderPayment, OrderPosition, OrderRefund, OutgoingMail, QuestionAnswer,
CachedCombinedTicket, CachedTicket, Event, InvoiceAddress, OrderPayment,
OrderPosition, OrderRefund, OutgoingMail, QuestionAnswer,
)
from pretix.base.services.invoices import invoice_pdf_task
from pretix.base.signals import register_data_shredders
@@ -598,30 +598,18 @@ class InvoiceShredder(BaseDataShredder):
def shred_data(self, progress_callback=None):
qs_i = self.event.invoices.filter(shredded=False)
total = qs_i.count()
ignore_fields = (
'prefix', 'invoice_no', 'full_invoice_no', 'invoice_from', 'invoice_from_name', 'invoice_from_zipcode',
'invoice_from_city', 'invoice_from_state', 'invoice_from_country', 'invoice_from_tax_id',
'invoice_from_vat_id', 'locale', 'payment_provider_stamp', 'footer_text', 'foreign_currency_display',
'foreign_currency_source', 'transmission_type', 'transmission_provider', 'transmission_status',
)
for i in _progress_helper(qs_i, progress_callback, 0, total):
if i.file:
i.file.delete()
i.shredded = True
for f in Invoice._meta.fields:
if f.name in ignore_fields:
continue
val = getattr(i, f.name, None)
if val and isinstance(val, str):
setattr(i, f.name, "█")
elif val and isinstance(val, list): # jsonfield
setattr(i, f.name, [])
elif val and isinstance(val, dict): # jsonfield
setattr(i, f.name, {"_shredded": True})
i.save()
i.lines.update(description="█", attendee_name="█")
i.shredded = True
i.introductory_text = "█"
i.additional_text = "█"
i.invoice_to = "█"
i.payment_provider_text = "█"
i.transmission_info = {"_shredded": True}
i.save()
i.lines.update(description="█")
class CachedTicketShredder(BaseDataShredder):
+8
View File
@@ -1207,3 +1207,11 @@ This signal is sent out each time the information for a Device is modified.
Both the original and updated versions of the Device are included to allow
receivers to see what has been updated.
"""
self_service_cancellation_checks = EventPluginSignal()
"""
This signal is sent out to collect checks to approve or deny a self service cancellation.
You are expected to return a class instance that implements CancellationCheck.
It is is expected that that the CheckFn will not issue any further queries.
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
"""
+23 -52
View File
@@ -20,7 +20,6 @@
# <https://www.gnu.org/licenses/>.
#
from decimal import ROUND_HALF_UP, Decimal
from typing import Optional
from babel import Locale, UnknownLocaleError
from babel.numbers import format_currency
@@ -36,32 +35,32 @@ register = template.Library()
@register.filter("money")
def money_filter(value: Optional[Decimal | float | int | str], arg='', hide_currency=False):
if isinstance(value, (float, int, str)):
if value == '':
return value
def money_filter(value: Decimal, arg='', hide_currency=False):
if isinstance(value, (float, int)):
value = Decimal(value)
if value is None:
value = Decimal('0.00')
if not isinstance(value, Decimal):
if value == '':
return value
raise TypeError("Invalid data type passed to money filter: %r" % type(value))
if not arg:
raise ValueError("No currency passed.")
arg = arg.upper()
if value.normalize().as_tuple().exponent < -9:
# Heuristic: It's unlikely we'll ever see values of less than 0.000000001 in any currency. Therefore, if we
# do see them, we very likely deal with a floating point error. This happens mostly in dev mode when computations
# are made in SQLite, which uses REAL precision, but it can also happen when we naively pass a float from Python
# land to this filter (even though it should not happen).
value = value.quantize(Decimal('1e-9'), ROUND_HALF_UP).normalize()
currency_places = settings.CURRENCY_PLACES.get(arg, 2)
required_places = -value.normalize().as_tuple().exponent
render_places = max(currency_places, required_places)
places = settings.CURRENCY_PLACES.get(arg, 2)
rounded = value.quantize(Decimal('1') / 10 ** places, ROUND_HALF_UP)
if places < 2 and rounded != value:
# We display decimal places even if we shouldn't for this currency if rounding
# would make the numbers incorrect. If this branch executes, it's likely a bug in
# pretix, but we won't show wrong numbers!
if hide_currency:
return floatformat(value, "2g")
else:
return '{} {}'.format(arg, floatformat(value, "2g"))
if hide_currency:
return floatformat(value, f"{render_places}g")
return floatformat(value, f"{places}g")
try:
locale = Locale(get_babel_locale())
@@ -69,29 +68,14 @@ def money_filter(value: Optional[Decimal | float | int | str], arg='', hide_curr
locale = "en"
try:
return format_currency(
value,
arg,
locale=locale,
# We only allow Babel to restrict the digits to the digits defined by the currency if this does not remove any
# precision in case we have sub-currency precision (which we shouldn't have in most places, but it's still
# better than showing wrong data). Note: Weird precision effects can occur after in-database arithmetic
# on SQLite, since SQLite does not have fixed-decimal computation.
currency_digits=currency_places >= required_places,
decimal_quantization=currency_places >= required_places,
)
return format_currency(value, arg, locale=locale)
except:
return '{} {}'.format(arg, floatformat(value, f"{render_places}g"))
@register.filter("money_without_currency")
def money_filter_without_currency(value: Optional[Decimal | float | int | str], arg=''):
return money_filter(value, arg, hide_currency=True)
return '{} {}'.format(arg, floatformat(value, f"{places}g"))
@register.filter("money_numberfield")
def money_numberfield_filter(value: Optional[Decimal | float | int | str], arg=''):
if isinstance(value, (float, int, str)):
def money_numberfield_filter(value: Decimal, arg=''):
if isinstance(value, (float, int)):
value = Decimal(value)
if not isinstance(value, Decimal):
raise TypeError("Invalid data type passed to money filter: %r" % type(value))
@@ -103,28 +87,15 @@ def money_numberfield_filter(value: Optional[Decimal | float | int | str], arg='
@register.filter(is_safe=True)
def tax_rate_format(number: Optional[Decimal | float | int | str]):
def tax_rate_format(number):
"""
Display a Decimal to its significant decimal places, used for tax rates.
"""
if isinstance(number, (float, int, str)):
if number == '':
return number
number = Decimal(number)
if number is None:
number = Decimal('0.00')
if not isinstance(number, Decimal):
raise TypeError("Invalid data type passed to tax rate format filter: %r" % type(number))
if number.normalize().as_tuple().exponent < -9:
# Heuristic: It's unlikely we'll ever see values of less than 0.000000001 in any currency. Therefore, if we
# do see them, we very likely deal with a floating point error. This happens mostly in dev mode when computations
# are made in SQLite, which uses REAL precision, but it can also happen when we naively pass a float from Python
# land to this filter (even though it should not happen).
number = number.quantize(Decimal('1e-9'), ROUND_HALF_UP).normalize()
assert isinstance(number, Decimal)
return mark_safe(
formats.number_format(
number,
-number.normalize().as_tuple().exponent,
number.normalize(),
-number.as_tuple().exponent,
use_l10n=True,
force_grouping=False,
)
+2 -2
View File
@@ -21,8 +21,8 @@
#
import contextvars
from contextlib import contextmanager
from datetime import datetime
from dateutil.parser import parse
from django.utils.timezone import now
from pretix.base.auth import has_event_access_permission
@@ -34,7 +34,7 @@ timemachine_now_var = contextvars.ContextVar('timemachine_now', default=None)
def time_machine_now_assigned_from_request(request):
if hasattr(request, 'event') and f'timemachine_now_dt:{request.event.pk}' in request.session and \
request.event.testmode and has_event_access_permission(request):
request.now_dt = datetime.fromisoformat(request.session[f'timemachine_now_dt:{request.event.pk}'])
request.now_dt = parse(request.session[f'timemachine_now_dt:{request.event.pk}'])
request.now_dt_is_fake = True
else:
request.now_dt = now()
+2 -7
View File
@@ -19,7 +19,6 @@
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
# <https://www.gnu.org/licenses/>.
#
from django.conf import settings
from django.http import (
HttpResponseForbidden, HttpResponseNotFound, HttpResponseServerError,
)
@@ -28,6 +27,7 @@ from django.template import TemplateDoesNotExist, loader
from django.template.loader import get_template
from django.utils.functional import Promise
from django.utils.translation import gettext as _
from sentry_sdk import last_event_id
from pretix.base.i18n import language
from pretix.base.middleware import get_language_from_request
@@ -106,14 +106,9 @@ def server_error(request):
template = loader.get_template('500.html')
except TemplateDoesNotExist:
return HttpResponseServerError('<h1>Server Error (500)</h1>', content_type='text/html')
if settings.SENTRY_ENABLED:
from sentry_sdk import last_event_id
sentry_id = last_event_id()
else:
sentry_id = None
r = HttpResponseServerError(template.render({
'request': request,
'sentry_event_id': sentry_id,
'sentry_event_id': last_event_id(),
}))
r.xframe_options_exempt = True
return r
-2
View File
@@ -135,8 +135,6 @@ class BaseQuestionsViewMixin:
question_field.initial = getattr(question_field, 'initial', None) or src['initial']
if 'validators' in src:
question_field.validators += src['validators']
if 'label' in src:
question_field.label = src['label']
if len(form.fields) > 0:
formlist.append(form)
-16
View File
@@ -20,7 +20,6 @@
# <https://www.gnu.org/licenses/>.
#
import logging
import multiprocessing
import os
from celery import Celery, signals
@@ -55,21 +54,6 @@ def on_task_received(sender, request, **kwargs):
logger.info(f"Task {request.id} has trace {trace}")
@receiver(signals.after_setup_task_logger)
def on_after_setup_task_logger(sender, logger, loglevel, logfile, format, colorize, **kwargs):
# This hack seems to be required to get celery to log internal events from eg billiard/pool.py such as
# "worker killed because it used too much memory"
# You can test that it is working by starting a celery worker with a low value like
# --max-memory-per-child 300000
# and then trigger a task. Result should look like this:
# [2026-09-23 10:42:26,234: WARNING/ForkPoolWorker-16]: [???:???] child process exiting after exceeding memory limit (394540KiB / 300000KiB)
# The ???:??? are likely because by copying the handlers, we are also copying the format, but I was unable to find
# a better compatible way.
multi_logger = multiprocessing.get_logger()
multi_logger.setLevel(logging.WARNING)
multi_logger.handlers = logger.handlers
@receiver(signals.task_prerun)
def on_task_prerun(sender, task_id, task, **kwargs):
from pretix.helpers.logs import local
+1 -12
View File
@@ -172,9 +172,7 @@ class CachedFileInput(forms.ClearableFileInput):
from ...base.models import CachedFile
v = super().value_from_datadict(data, files, name)
if v is None and data.get(name + '-cachedfile'): # An explicit "[x] clear" would be False, not None
v = CachedFile.objects.filter(id=data[name + '-cachedfile']).first()
if not v.allowed_for_session(self.request):
v = None
return CachedFile.objects.filter(id=data[name + '-cachedfile']).first()
return v
def get_context(self, name, value, attrs):
@@ -246,11 +244,6 @@ class ExtFileField(ExtValidationMixin, SizeFileField):
class CachedFileField(ExtFileField):
widget = CachedFileInput
def __init__(self, *args, **kwargs):
self.request = kwargs.pop("request", None)
super().__init__(*args, **kwargs)
self.widget.request = self.request
def to_python(self, data):
from ...base.models import CachedFile
@@ -278,8 +271,6 @@ class CachedFileField(ExtFileField):
filename=data.name,
type=data.content_type,
)
if self.request:
cf.bind_to_session(self.request) # no salt because we want direct web access
cf.file.save(data.name, data.file)
cf.save()
data._uploaded_to = cf
@@ -303,8 +294,6 @@ class CachedFileField(ExtFileField):
filename=data.name,
type=data.content_type,
)
if self.request:
cf.bind_to_session(self.request) # no salt because we want direct web access
cf.file.save(data.name, data.file)
cf.save()
data._uploaded_to = cf
+10 -23
View File
@@ -400,10 +400,10 @@ class EventMetaValueForm(forms.ModelForm):
if self.disabled:
self.fields['value'].widget.attrs['readonly'] = 'readonly'
def clean_value(self):
def clean_slug(self):
if self.disabled:
return self.instance.value if self.instance else None
return self.cleaned_data['value']
return self.cleaned_data['slug']
class Meta:
model = EventMetaValue
@@ -838,10 +838,9 @@ class CancelSettingsForm(SettingsForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if self.obj.settings.giftcard_expiry_years is not None:
self.fields['cancel_allow_user_paid_refund_as_giftcard'].help_text = format_html(
gettext('You have configured gift cards to be valid {} years plus the year the gift card is issued in.'),
self.obj.settings.giftcard_expiry_years
)
self.fields['cancel_allow_user_paid_refund_as_giftcard'].help_text = gettext(
'You have configured gift cards to be valid {} years plus the year the gift card is issued in.'
).format(self.obj.settings.giftcard_expiry_years)
class PaymentSettingsForm(EventSettingsValidationMixin, SettingsForm):
@@ -856,21 +855,14 @@ class PaymentSettingsForm(EventSettingsValidationMixin, SettingsForm):
'payment_term_accept_late',
'payment_pending_hidden',
'payment_explanation',
'payment_choice_postpone_allowed_channels',
'tax_rule_payment',
]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
channels = list(self.obj.organizer.sales_channels.all())
self.fields['payment_choice_postpone_allowed_channels'].choices = [
(c.identifier, c.label) for c in channels
if c.type_instance.payment_restrictions_supported
]
self.term_channel_fields = {}
for c in channels:
for c in self.obj.organizer.sales_channels.all():
if c.type_instance.payment_restrictions_supported and c.identifier != "web":
# At the moment, it seems sufficient to allow this for the same channel types as other payment settings
# We can always introduce more flags later if needed
@@ -1636,15 +1628,10 @@ class MailSettingsForm(FormPlaceholderMixin, SettingsForm):
self._set_field_placeholders(k, v, rich=k.startswith('mail_text_') and k not in self.plain_rendering)
for k, v in list(self.fields.items()):
if k.endswith('_attendee'):
if not event.settings.attendee_emails_asked:
# If we don't ask for attendee emails, we can't send them anything and we don't need to clutter
# the user interface with it
del self.fields[k]
elif 'subject' in k and k.replace("subject", "send") in self.fields:
v.widget.attrs["data-display-dependency"] = f'#id_{k.replace("subject", "send")}'
elif 'text' in k and k.replace("text", "send") in self.fields:
v.widget.attrs["data-display-dependency"] = f'#id_{k.replace("text", "send")}'
if k.endswith('_attendee') and not event.settings.attendee_emails_asked:
# If we don't ask for attendee emails, we can't send them anything and we don't need to clutter
# the user interface with it
del self.fields[k]
class TicketSettingsForm(SettingsForm):
@@ -105,6 +105,13 @@ class GlobalSettingsForm(SettingsForm):
domain=settings.SITE_URL
)
)),
('widget_vite_origins', forms.CharField(
widget=forms.Textarea(attrs={'rows': '3'}),
required=False,
# Not translated on purpose, this is a temporary feature and contains too many special case words
label="Vite widget origins",
help_text="One origin per line (e.g. https://example.com). Requests from these origins will be served the new vite-based widget.",
))
])
responses = register_global_settings.send(self)
for r, response in sorted(responses, key=lambda r: str(r[0])):
+2 -2
View File
@@ -22,7 +22,7 @@
from django import forms
from django.core.exceptions import ValidationError
from django.utils.functional import lazy
from django.utils.html import conditional_escape, format_html
from django.utils.html import format_html
from django.utils.translation import gettext_lazy as _
from pretix.base.modelimport_orders import get_order_import_columns
@@ -66,7 +66,7 @@ class ProcessForm(forms.Form):
widget=forms.Select(
attrs={'data-static': 'true'}
),
help_text=conditional_escape(c.help_text),
help_text=c.help_text,
)
def get_columns(self):
+2 -2
View File
@@ -364,7 +364,7 @@ class TeamForm(forms.ModelForm):
for opt in pg.options
],
label=pg.label,
help_text=conditional_escape(pg.help_text),
help_text=pg.help_text,
initial=initial,
widget=forms.RadioSelect,
)
@@ -389,7 +389,7 @@ class TeamForm(forms.ModelForm):
for opt in pg.options
],
label=pg.label,
help_text=conditional_escape(pg.help_text),
help_text=pg.help_text,
initial=initial,
widget=forms.RadioSelect,
)
-2
View File
@@ -87,7 +87,6 @@ class RRuleForm(forms.Form):
('1', pgettext_lazy('rrule', 'first')),
('2', pgettext_lazy('rrule', 'second')),
('3', pgettext_lazy('rrule', 'third')),
('4', pgettext_lazy('rrule', 'fourth')),
('-1', pgettext_lazy('rrule', 'last')),
],
required=False
@@ -135,7 +134,6 @@ class RRuleForm(forms.Form):
('1', pgettext_lazy('rrule', 'first')),
('2', pgettext_lazy('rrule', 'second')),
('3', pgettext_lazy('rrule', 'third')),
('4', pgettext_lazy('rrule', 'fourth')),
('-1', pgettext_lazy('rrule', 'last')),
],
required=False
+2 -2
View File
@@ -435,10 +435,10 @@ class SubEventMetaValueForm(forms.ModelForm):
if self.disabled:
self.fields['value'].widget.attrs['readonly'] = 'readonly'
def clean_value(self):
def clean_slug(self):
if self.disabled:
return self.instance.value if self.instance else None
return self.cleaned_data['value']
return self.cleaned_data['slug']
class Meta:
model = SubEventMetaValue
+1 -2
View File
@@ -44,7 +44,6 @@ from django.db.models import Count, F, Max
from django.db.models.functions import Upper
from django.forms.utils import ErrorDict
from django.urls import reverse
from django.utils.html import escape
from django.utils.timezone import now
from django.utils.translation import gettext_lazy as _, pgettext_lazy
from django_scopes.forms import SafeModelChoiceField
@@ -177,7 +176,7 @@ class VoucherForm(I18nModelForm):
required=False,
widget=forms.TextInput(attrs={'data-seat-guid-field': '1'}),
initial=self.instance.seat.seat_guid if self.instance.seat else '',
help_text=escape(str(self.instance.seat) if self.instance.seat else ''),
help_text=str(self.instance.seat) if self.instance.seat else '',
)
def parse_itemvar(self, data):
-5
View File
@@ -717,10 +717,6 @@ class CoreUserImpersonatedLogEntryType(UserImpersonatedLogEntryType):
'pretix.organizer.export.schedule.failed': _('A scheduled export has failed: {reason}.'),
'pretix.organizer.outgoingmails.retried': _('Failed emails have been scheduled to be retried.'),
'pretix.organizer.outgoingmails.aborted': _('Queued emails have been aborted.'),
'pretix.property.created': _('An organizer meta property has been created.'),
'pretix.property.deleted': _('An organizer meta property has been deleted.'),
'pretix.property.changed': _('An organizer meta property has been changed.'),
'pretix.property.reordered': _('An organizer meta property has been reordered.'),
'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.giftcards.acceptance.acceptor.invited': _('A new gift card acceptor has been invited.'),
@@ -778,7 +774,6 @@ class CoreUserImpersonatedLogEntryType(UserImpersonatedLogEntryType):
'pretix.user.settings.2fa.disabled': _('Two-factor authentication has been disabled.'),
'pretix.user.settings.2fa.regenemergency': _('Your two-factor emergency codes have been regenerated.'),
'pretix.user.settings.2fa.emergency': _('A two-factor emergency code has been generated.'),
'pretix.user.settings.2fa.resetdrift': _('Drift and throttle values for two-factor devices have been reset.'),
'pretix.user.settings.2fa.device.added': _('A new two-factor authentication device "{name}" has been added to '
'your account.'),
'pretix.user.settings.2fa.device.deleted': _('The two-factor authentication device "{name}" has been removed '
+2 -2
View File
@@ -85,8 +85,8 @@ class PermissionMiddleware:
"user.settings.2fa.enable",
"user.settings.2fa.disable",
"user.settings.2fa.regenemergency",
"user.settings.2fa.confirm.otp_totp.totpdevice",
"user.settings.2fa.confirm.pretixbase.webauthndevice",
"user.settings.2fa.confirm.totp",
"user.settings.2fa.confirm.webauthn",
"user.settings.2fa.delete",
"user.settings.2fa.leaveteams",
"auth.logout",
@@ -45,8 +45,8 @@
</p>
<div class="form-group buttons">
<input type="submit" class="btn btn-large btn-default" value="{% trans "Cancel" %}"/>
<input type="submit" class="btn btn-large btn-primary" name="allow" value="{% trans "Authorize" %}"/>
<input type="submit" class="btn btn-large btn-default" value="Cancel"/>
<input type="submit" class="btn btn-large btn-primary" name="allow" value="Authorize"/>
</div>
</form>
{% else %}
@@ -109,7 +109,6 @@
{% bootstrap_form_errors form layout="control" %}
{% bootstrap_field form.tax_rule_payment layout="control" %}
{% bootstrap_field form.payment_explanation layout="control" %}
{% bootstrap_field form.payment_choice_postpone_allowed_channels layout="control" %}
</fieldset>
</div>
{% if "event.settings.payment:write" in request.eventpermset %}
@@ -33,7 +33,7 @@
</div>
<div class="slug-length alert alert-warning helper-display-none-soft">
{% blocktrans trimmed %}
We strongly recommend against using short forms of more than 16 characters.
We strongly recommend against using short forms of more then 16 characters.
{% endblocktrans %}
</div>
</div>
@@ -15,7 +15,7 @@
<div>
<div class="big-radio radio">
<label>
<input type="radio" required value="otp_totp.totpdevice" name="{{ form.devicetype.html_name }}" {% if form.devicetype.value == "otp_totp.totpdevice" %}checked{% endif %}>
<input type="radio" required value="totp" name="{{ form.devicetype.html_name }}" {% if form.devicetype.value == "totp" %}checked{% endif %}>
<strong>{% trans "Smartphone with Authenticator app" %}</strong><br>
<div class="help-block">
{% blocktrans trimmed %}
@@ -26,7 +26,7 @@
</div>
<div class="big-radio radio">
<label>
<input type="radio" required value="pretixbase.webauthndevice" name="{{ form.devicetype.html_name }}" {% if form.devicetype.value == "pretixbase.webauthndevice" %}checked{% endif %}>
<input type="radio" required value="webauthn" name="{{ form.devicetype.html_name }}" {% if form.devicetype.value == "webauthn" %}checked{% endif %}>
<strong>{% trans "WebAuthn-compatible hardware token" %}</strong><br>
<div class="help-block">
{% blocktrans trimmed %}
@@ -116,14 +116,14 @@
{% for d in devices %}
<li class="list-group-item">
<a class="btn btn-danger btn-xs pull-right flip"
href="{% url "control:user.settings.2fa.delete" devicetype=d.model_label device=d.pk %}">
href="{% url "control:user.settings.2fa.delete" devicetype=d.devicetype device=d.pk %}">
Delete
</a>
{% if d.model_label == "otp_totp.totpdevice" %}
{% if d.devicetype == "totp" %}
<span class="fa fa-mobile"></span>
{% elif d.model_label == "pretixbase.webauthndevice" %}
{% elif d.devicetype == "webauthn" %}
<span class="fa fa-usb"></span>
{% elif d.model_label == "pretixbase.u2fdevice" %}
{% elif d.devicetype == "u2f" %}
<span class="fa fa-usb"></span>
{% endif %}
{{ d.name }}
@@ -1,7 +1,6 @@
{% extends "pretixcontrol/base.html" %}
{% load i18n %}
{% load bootstrap3 %}
{% load icon %}
{% block title %}{% trans "User" %}{% endblock %}
{% block content %}
<h1>{% trans "User" %} {{ user.email }}</h1>
@@ -60,83 +59,8 @@
{% bootstrap_field form.is_verified layout='control' %}
{% endif %}
{% bootstrap_field form.last_login layout='control' %}
{% bootstrap_field form.needs_password_change layout='control' %}
{% bootstrap_field form.require_2fa layout='control' %}
<div class="form-group">
<div class="col-md-9 col-md-offset-3">
<div class="panel panel-default">
<div class="panel-heading">
<button class="btn btn-default btn-xs pull-right" type="submit" form="resetdriftthrottle">
{% trans "Reset drift and throttle" %}
</button>
<h3 class="panel-title">
{% trans "Available two-factor authentication methods" %}
</h3>
</div>
<table class="panel-body table table-hover">
{% for d in devices %}
<tr>
<td>
{% if d.model_label == 'otp_totp.totpdevice' %}
TOTP
{% elif d.model_label == 'pretixbase.u2fdevice' %}
U2F
{% elif d.model_label == 'pretixbase.webauthndevice' %}
WebAuthn
{% elif d.model_label == 'otp_static.staticdevice' %}
{% trans "Emergency tokens" %}
{% endif %}
{% if d.confirmed %}
{% icon "check" %}
{% else %}
{% icon "warning" %}
{% endif %}
</td>
<td>
{{ d.name }}
</td>
<td>
{% if d.throttling_failure_timestamp %}
{% blocktrans trimmed with date=d.throttling_failure_timestamp|date:"SHORT_DATETIME_FORMAT" count cnt=d.throttling_failure_count %}
1 failed attempt since {{ date }}
{% plural %}
{{ cnt }} failed attempts since {{ date }}
{% endblocktrans %}
<br>
{% endif %}
{% if d.throttling_enabled and not d.verify_is_allowed.0 %}
<strong>
{% blocktrans trimmed with date=d.verify_is_allowed.1.locked_until|date:"SHORT_DATETIME_FORMAT" %}
Currently locked until {{ date }}
{% endblocktrans %}
</strong>
<br>
{% endif %}
{% if d.model_label == 'otp_totp.totpdevice' %}
<small>
<code>step = {{ d.step }},
t0 = {{ d.t0 }},
digits = {{ d.digits }},
tolerance = {{ d.tolerance }},
drift = {{ d.drift }},
last_t = {{ d.last_t }}</code>
</small>
{% elif d.model_label == 'pretixbase.u2fdevice' %}
<small>
<code>sign_count = {{ d.sign_count }}</code>
</small>
{% elif d.model_label == 'otp_static.staticdevice' %}
<small>
<code>token_count = {{ d.token_set.count }}</code>
</small>
{% endif %}
</td>
</tr>
{% endfor %}
</table>
</div>
</div>
</div>
{% bootstrap_field form.needs_password_change layout='control' %}
</fieldset>
<fieldset>
<legend>{% trans "Team memberships" %}</legend>
@@ -178,8 +102,4 @@
</div>
</div>
</div>
<form action="{% url "control:users.resetdriftthrottle" id=user.pk %}" id="resetdriftthrottle" method="post">
{% csrf_token %}
</form>
{% endblock %}
+2 -3
View File
@@ -78,7 +78,6 @@ urlpatterns = [
re_path(r'^users/(?P<id>\d+)/impersonate$', users.UserImpersonateView.as_view(), name='users.impersonate'),
re_path(r'^users/(?P<id>\d+)/anonymize$', users.UserAnonymizeView.as_view(), name='users.anonymize'),
re_path(r'^users/(?P<id>\d+)/emergencytoken$', users.UserEmergencyTokenView.as_view(), name='users.emergencytoken'),
re_path(r'^users/(?P<id>\d+)/resetdriftthrottle$', users.Reset2FADriftThrottleView.as_view(), name='users.resetdriftthrottle'),
re_path(r'^pdf/editor/webfonts.css', pdf.FontsCSSView.as_view(), name='pdf.css'),
re_path(r'^settings/?$', user.UserSettings.as_view(), name='user.settings'),
re_path(r'^settings/history/$', user.UserHistoryView.as_view(), name='user.settings.history'),
@@ -107,9 +106,9 @@ urlpatterns = [
re_path(r'^settings/2fa/regenemergency', user.User2FARegenerateEmergencyView.as_view(),
name='user.settings.2fa.regenemergency'),
re_path(r'^settings/2fa/totp/(?P<device>[0-9]+)/confirm', user.User2FADeviceConfirmTOTPView.as_view(),
name='user.settings.2fa.confirm.otp_totp.totpdevice'),
name='user.settings.2fa.confirm.totp'),
re_path(r'^settings/2fa/webauthn/(?P<device>[0-9]+)/confirm', user.User2FADeviceConfirmWebAuthnView.as_view(),
name='user.settings.2fa.confirm.pretixbase.webauthndevice'),
name='user.settings.2fa.confirm.webauthn'),
re_path(r'^settings/2fa/(?P<devicetype>[^/]+)/(?P<device>[0-9]+)/delete', user.User2FADeviceDeleteView.as_view(),
name='user.settings.2fa.delete'),
re_path(r'^settings/email/confirm$', user.UserEmailConfirmView.as_view(), name='user.settings.email.confirm'),
+15 -53
View File
@@ -35,7 +35,6 @@
import base64
import json
import logging
import math
import time
from urllib.parse import quote, urljoin, urlparse
@@ -51,12 +50,11 @@ from django.shortcuts import redirect, render
from django.urls import reverse
from django.utils.functional import cached_property
from django.utils.http import url_has_allowed_host_and_scheme
from django.utils.timezone import now
from django.utils.translation import gettext_lazy as _, ngettext
from django.utils.translation import gettext_lazy as _
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_http_methods
from django.views.generic import TemplateView
from django_otp import devices_for_user
from django_otp import match_token
from django_otp.plugins.otp_static.models import StaticDevice
from webauthn.helpers import generate_challenge
@@ -66,7 +64,6 @@ from pretix.base.forms.auth import (
)
from pretix.base.metrics import pretix_failed_logins, pretix_successful_logins
from pretix.base.models import TeamInvite, U2FDevice, User, WebAuthnDevice
from pretix.helpers import OF_SELF
from pretix.helpers.http import get_client_ip, redirect_to_url
from pretix.helpers.ratelimit import rate_limit, rate_limit_reset
from pretix.helpers.security import handle_login_source, session_login
@@ -398,17 +395,15 @@ class Recover(TemplateView):
def post(self, request, *args, **kwargs):
if self.form.is_valid():
with transaction.atomic():
# Check token in transaction to prevent race condition
try:
user = User.objects.select_for_update(of=OF_SELF).get(id=self.request.GET.get('id'), auth_backend='native')
except User.DoesNotExist:
return self.invalid('unknownuser')
if not default_token_generator.check_token(user, self.request.GET.get('token')):
return self.invalid('invalid')
user.set_password(self.form.cleaned_data['password'])
user.needs_password_change = False
user.save()
try:
user = User.objects.get(id=self.request.GET.get('id'), auth_backend='native')
except User.DoesNotExist:
return self.invalid('unknownuser')
if not default_token_generator.check_token(user, self.request.GET.get('token')):
return self.invalid('invalid')
user.set_password(self.form.cleaned_data['password'])
user.needs_password_change = False
user.save()
messages.success(request, _('You can now login using your new password.'))
user.log_action('pretix.control.auth.user.forgot_password.recovered')
@@ -465,7 +460,6 @@ class Login2FAView(TemplateView):
token = request.POST.get('token', '').strip().replace(' ', '')
valid = False
retry_after = None
if 'webauthn_challenge' in self.request.session and token.startswith('{'):
challenge = self.request.session['webauthn_challenge']
@@ -521,28 +515,12 @@ class Login2FAView(TemplateView):
valid = True
break
else:
with transaction.atomic():
for device in devices_for_user(self.user, for_verify=True):
if isinstance(device, StaticDevice) and len(token) < 12:
# If we enter a wrong TOTP token (which is 6 characters), do not even try if it is a valid
# emergency token, which will only "lock up" the StaticDevice due to the throttling plugin
# and just locks people out without security gain.
continue
if device.verify_token(token):
valid = True
break
elif hasattr(device, 'verify_is_allowed'):
verify_allowed, reason_dict = device.verify_is_allowed()
if not verify_allowed:
if not retry_after or reason_dict['locked_until'] > retry_after:
retry_after = reason_dict['locked_until']
else:
device = None
if isinstance(device, StaticDevice):
valid = match_token(self.user, token)
if isinstance(valid, StaticDevice):
self.user.send_security_notice([
_("A recovery code for two-factor authentification was used to log in.")
])
if valid:
logger.info(f"Backend login successful for user {self.user.pk} with 2FA.")
pretix_successful_logins.inc(1)
@@ -555,23 +533,7 @@ class Login2FAView(TemplateView):
return redirect('control:index')
else:
pretix_failed_logins.inc(1, reason="2fa")
msg = _('Invalid code, please try again.')
if retry_after:
seconds = (retry_after - now()).total_seconds()
minutes = seconds / 60
if minutes >= 1:
msg = ngettext(
'Invalid code. Please try again after waiting {value} minute.',
'Invalid code. Please try again after waiting {value} minutes.',
minutes,
).format(value=math.ceil(minutes))
elif seconds >= 1:
msg = ngettext(
'Invalid code. Please try again after waiting {value} second.',
'Invalid code. Please try again after waiting {value} seconds.',
seconds,
).format(value=math.ceil(seconds))
messages.error(request, msg)
messages.error(request, _('Invalid code, please try again.'))
return redirect('control:auth.login.2fa')
def get_context_data(self, **kwargs):
+2 -5
View File
@@ -402,12 +402,9 @@ def event_index_widgets_lazy(request, organizer, event):
except SubEvent.DoesNotExist:
pass
can_view_orders = request.user.has_event_permission(request.organizer, request.event, 'event.orders:read',
request=request)
widgets = []
if can_view_orders:
for r, result in event_dashboard_widgets.send(sender=request.event, subevent=subevent, lazy=False):
widgets.extend(result)
for r, result in event_dashboard_widgets.send(sender=request.event, subevent=subevent, lazy=False):
widgets.extend(result)
return build_json_response(widgets)
-3
View File
@@ -163,9 +163,6 @@ class DiscountCreate(EventPermissionRequiredMixin, CreateView):
i = modelcopy(self.copy_from)
i.pk = None
kwargs['instance'] = i
kwargs["initial"]["limit_sales_channels"] = self.copy_from.limit_sales_channels.all()
kwargs["initial"]["condition_limit_products"] = self.copy_from.condition_limit_products.all()
kwargs["initial"]["benefit_limit_products"] = self.copy_from.benefit_limit_products.all()
else:
kwargs['instance'] = Discount(event=self.request.event)
+5 -22
View File
@@ -1177,8 +1177,6 @@ class OrderRefundView(OrderView):
manual_value = formats.sanitize_separators(manual_value)
try:
manual_value = Decimal(manual_value)
if manual_value < Decimal("0.00"):
raise TypeError("Please do not use negative numbers")
except (DecimalException, TypeError):
messages.error(self.request, _('You entered an invalid number.'))
is_valid = False
@@ -1208,8 +1206,6 @@ class OrderRefundView(OrderView):
giftcard_value = formats.sanitize_separators(giftcard_value)
try:
giftcard_value = Decimal(giftcard_value)
if giftcard_value < Decimal("0.00"):
raise TypeError("Please do not use negative numbers")
except (DecimalException, TypeError):
messages.error(self.request, _('You entered an invalid number.'))
is_valid = False
@@ -1259,8 +1255,6 @@ class OrderRefundView(OrderView):
offsetting_value = formats.sanitize_separators(offsetting_value)
try:
offsetting_value = Decimal(offsetting_value)
if offsetting_value < Decimal("0.00"):
raise TypeError("Please do not use negative numbers")
except (DecimalException, TypeError):
messages.error(self.request, _('You entered an invalid number.'))
is_valid = False
@@ -1277,9 +1271,6 @@ class OrderRefundView(OrderView):
if offset_order.event.currency != self.request.event.currency:
messages.error(self.request, _('You entered an order in an event with a different currency.'))
is_valid = False
if not self.request.user.has_event_permission(self.request.organizer, offset_order.event, 'event.orders:write', request=self.request):
messages.error(self.request, _('You entered an order in an event that you do not have access to.'))
is_valid = False
refunds.append(OrderRefund(
order=order,
payment=None,
@@ -1295,13 +1286,10 @@ class OrderRefundView(OrderView):
))
for identifier, prov in self.request.event.get_payment_providers().items():
# prof = process form, not a typo for prov(ider)
prof_value = self.request.POST.get(f'newrefund-{identifier}', '0') or '0'
prof_value = formats.sanitize_separators(prof_value)
try:
prof_value = Decimal(prof_value)
if prof_value < Decimal("0.00"):
raise TypeError("Please do not use negative numbers")
except (DecimalException, TypeError):
messages.error(self.request, _('You entered an invalid number.'))
is_valid = False
@@ -1325,8 +1313,6 @@ class OrderRefundView(OrderView):
value = formats.sanitize_separators(value)
try:
value = Decimal(value)
if value < Decimal("0.00"):
raise TypeError("Please do not use negative numbers")
except (DecimalException, TypeError):
messages.error(self.request, _('You entered an invalid number.'))
is_valid = False
@@ -1356,12 +1342,7 @@ class OrderRefundView(OrderView):
))
any_success = False
if refund_selected != full_refund:
messages.error(self.request, _('The refunds you selected do not match the selected total refund '
'amount.'))
is_valid = False
if is_valid:
if refund_selected == full_refund and is_valid:
for r in refunds:
r.save()
order.log_action('pretix.event.order.refund.created', {
@@ -1433,6 +1414,9 @@ class OrderRefundView(OrderView):
)
}))
return redirect(self.get_order_url())
else:
messages.error(self.request, _('The refunds you selected do not match the selected total refund '
'amount.'))
def post(self, *args, **kwargs):
if self.start_form.is_valid():
@@ -1662,8 +1646,7 @@ class OrderCheckVATID(OrderView):
return redirect(self.get_order_url())
try:
requester_id = self.request.event.settings.invoice_address_from_vat_id
normalized_id = validate_vat_id(ia.vat_id, str(ia.country), requester_id)
normalized_id = validate_vat_id(ia.vat_id, str(ia.country))
with transaction.atomic():
ia.vat_id_validated = True
ia.vat_id = normalized_id
+4 -4
View File
@@ -778,9 +778,9 @@ class OrganizerPluginEvents(OrganizerDetailViewMixin, OrganizerPermissionRequire
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
# Assumption: Who has access to modify organizer settings may see all events and disable/enable plugins
# for them. Otherwise, inconsistent situations occur.
kwargs["events"] = self.request.organizer.events.all()
kwargs["events"] = self.request.user.get_events_with_permission(
"event.settings.general:write", request=self.request
).filter(organizer=self.request.organizer)
kwargs["initial"] = {
"events": self.request.organizer.events.filter(plugins__regex='(^|,)' + self.plugin.module + '(,|$)')
}
@@ -2202,7 +2202,7 @@ class ExportView(OrganizerPermissionRequiredMixin, ExportMixin, ListView):
owner=self.request.user,
timezone=str(get_current_timezone()),
)
if not self.scheduled and not self.scheduled_copy_from:
if not self.scheduled:
initial = {
"mail_subject": gettext("Export: {title}").format(title=self.exporter.verbose_name),
"mail_template": gettext(
-5
View File
@@ -27,7 +27,6 @@ from decimal import Decimal
from io import BytesIO
from django.conf import settings
from django.core.exceptions import PermissionDenied
from django.core.files import File
from django.core.files.base import ContentFile
from django.core.files.storage import default_storage
@@ -194,7 +193,6 @@ class BaseEditorView(EventPermissionRequiredMixin, TemplateView):
c.expires = now() + timedelta(days=7)
c.date = now()
c.filename = 'background_preview.pdf'
c.bind_to_session(request, "ticketoutput-pdf-background")
c.type = 'application/pdf'
c.save()
c.file.save('empty.pdf', ContentFile(buffer.read()))
@@ -220,7 +218,6 @@ class BaseEditorView(EventPermissionRequiredMixin, TemplateView):
c.expires = now() + timedelta(days=7)
c.date = now()
c.filename = 'background_preview.pdf'
c.bind_to_session(request, "ticketoutput-pdf-background")
c.type = 'application/pdf'
c.file = fileobj
c.save()
@@ -306,7 +303,5 @@ class FontsCSSView(TemplateView):
class PdfView(TemplateView):
def get(self, request, *args, **kwargs):
cf = get_object_or_404(CachedFile, id=kwargs.get("filename"), filename="background_preview.pdf")
if not cf.allowed_for_session(request, "ticketoutput-pdf-background"):
raise PermissionDenied()
resp = FileResponse(cf.file, filename=cf.filename, content_type='application/pdf')
return resp
-5
View File
@@ -1276,11 +1276,6 @@ class SubEventBulkEdit(SubEventQueryMixin, EventPermissionRequiredMixin, FormVie
self._default_meta = self.request.event.meta_data
for p in self.request.organizer.meta_properties.all():
if p.protected and not self.request.user.has_organizer_permission(
self.request.organizer, 'organizer.settings.general:write', request=self.request
):
continue
inst = SubEventMetaValue(property=p)
if len(matches[p.id]) == 1 and matches[p.id][0]['c'] == total:
inst.value = matches[p.id][0]['value']
+25 -15
View File
@@ -59,7 +59,6 @@ from django.utils.translation import gettext_lazy as _
from django.views import View
from django.views.decorators.cache import never_cache
from django.views.generic import FormView, ListView, TemplateView, UpdateView
from django_otp import devices_for_user
from django_otp.plugins.otp_static.models import StaticDevice
from django_otp.plugins.otp_totp.models import TOTPDevice
from django_scopes import scopes_disabled
@@ -86,6 +85,7 @@ from pretix.helpers.ratelimit import rate_limit, rate_limit_reset
from pretix.helpers.security import session_reauth
from pretix.helpers.u2f import websafe_encode
REAL_DEVICE_TYPES = (TOTPDevice, WebAuthnDevice, U2FDevice)
logger = logging.getLogger(__name__)
@@ -313,7 +313,17 @@ class User2FAMainView(RecentAuthenticationRequiredMixin, TemplateView):
except StaticDevice.DoesNotExist:
ctx['static_tokens_device'] = None
ctx['devices'] = [d for d in devices_for_user(self.request.user) if not isinstance(d, StaticDevice)]
ctx['devices'] = []
for dt in REAL_DEVICE_TYPES:
objs = list(dt.objects.filter(user=self.request.user, confirmed=True))
for obj in objs:
if dt == TOTPDevice:
obj.devicetype = 'totp'
elif dt == U2FDevice:
obj.devicetype = 'u2f'
elif dt == WebAuthnDevice:
obj.devicetype = 'webauthn'
ctx['devices'] += objs
ctx['obligatory'] = None
if settings.PRETIX_OBLIGATORY_2FA is True:
@@ -332,9 +342,9 @@ class User2FADeviceAddView(RecentAuthenticationRequiredMixin, FormView):
template_name = 'pretixcontrol/user/2fa_add.html'
def form_valid(self, form):
if form.cleaned_data['devicetype'] == 'otp_totp.totpdevice':
if form.cleaned_data['devicetype'] == 'totp':
dev = TOTPDevice.objects.create(user=self.request.user, confirmed=False, name=form.cleaned_data['name'])
elif form.cleaned_data['devicetype'] == 'pretixbase.webauthndevice':
elif form.cleaned_data['devicetype'] == 'webauthn':
if not self.request.is_secure():
messages.error(self.request,
_('Security devices are only available if pretix is served via HTTPS.'))
@@ -354,11 +364,11 @@ class User2FADeviceDeleteView(RecentAuthenticationRequiredMixin, TemplateView):
@cached_property
def device(self):
if self.kwargs['devicetype'] == 'otp_totp.totpdevice':
if self.kwargs['devicetype'] == 'totp':
return get_object_or_404(TOTPDevice, user=self.request.user, pk=self.kwargs['device'], confirmed=True)
elif self.kwargs['devicetype'] == 'pretixbase.webauthndevice':
elif self.kwargs['devicetype'] == 'webauthn':
return get_object_or_404(WebAuthnDevice, user=self.request.user, pk=self.kwargs['device'], confirmed=True)
elif self.kwargs['devicetype'] == 'pretixbase.u2fdevice':
elif self.kwargs['devicetype'] == 'u2f':
return get_object_or_404(U2FDevice, user=self.request.user, pk=self.kwargs['device'], confirmed=True)
def get_context_data(self, **kwargs):
@@ -376,7 +386,7 @@ class User2FADeviceDeleteView(RecentAuthenticationRequiredMixin, TemplateView):
msgs = [
_('A two-factor authentication device has been removed from your account.')
]
if not any(d.confirmed for d in devices_for_user(self.request.user) if not isinstance(d, StaticDevice)):
if not any(dt.objects.filter(user=self.request.user, confirmed=True) for dt in REAL_DEVICE_TYPES):
self.request.user.require_2fa = False
self.request.user.save()
self.request.user.log_action('pretix.user.settings.2fa.disabled', user=self.request.user)
@@ -451,7 +461,7 @@ class User2FADeviceConfirmWebAuthnView(RecentAuthenticationRequiredMixin, Templa
).first()
if credential_id_exists:
messages.error(request, _('This security device is already registered.'))
return redirect(reverse('control:user.settings.2fa.confirm.pretixbase.webauthndevice', kwargs={
return redirect(reverse('control:user.settings.2fa.confirm.webauthn', kwargs={
'device': self.device.pk
}))
@@ -465,7 +475,7 @@ class User2FADeviceConfirmWebAuthnView(RecentAuthenticationRequiredMixin, Templa
self.device.save()
self.request.user.log_action('pretix.user.settings.2fa.device.added', user=self.request.user, data={
'id': self.device.pk,
'devicetype': 'pretixbase.webauthndevice',
'devicetype': 'u2f',
'name': self.device.name,
})
notices = [
@@ -493,7 +503,7 @@ class User2FADeviceConfirmWebAuthnView(RecentAuthenticationRequiredMixin, Templa
except Exception:
messages.error(request, _('The registration could not be completed. Please try again.'))
logger.exception('WebAuthn registration failed')
return redirect(reverse('control:user.settings.2fa.confirm.pretixbase.webauthndevice', kwargs={
return redirect(reverse('control:user.settings.2fa.confirm.webauthn', kwargs={
'device': self.device.pk
}))
@@ -527,7 +537,7 @@ class User2FADeviceConfirmTOTPView(RecentAuthenticationRequiredMixin, TemplateVi
self.request.user.log_action('pretix.user.settings.2fa.device.added', user=self.request.user, data={
'id': self.device.pk,
'name': self.device.name,
'devicetype': 'otp_totp.totpdevice'
'devicetype': 'totp'
})
notices = [
_('A new two-factor authentication device has been added to your account.')
@@ -553,7 +563,7 @@ class User2FADeviceConfirmTOTPView(RecentAuthenticationRequiredMixin, TemplateVi
else:
messages.error(request, _('The code you entered was not valid. If this problem persists, please check '
'that the date and time of your phone are configured correctly.'))
return redirect(reverse('control:user.settings.2fa.confirm.otp_totp.totpdevice', kwargs={
return redirect(reverse('control:user.settings.2fa.confirm.totp', kwargs={
'device': self.device.pk
}))
@@ -584,7 +594,7 @@ class User2FAEnableView(RecentAuthenticationRequiredMixin, TemplateView):
template_name = 'pretixcontrol/user/2fa_enable.html'
def dispatch(self, request, *args, **kwargs):
if not any(d.confirmed for d in devices_for_user(self.request.user) if not isinstance(d, StaticDevice)):
if not any(dt.objects.filter(user=self.request.user, confirmed=True) for dt in REAL_DEVICE_TYPES):
messages.error(request, _('Please configure at least one device before enabling two-factor '
'authentication.'))
return redirect(reverse('control:user.settings.2fa'))
@@ -946,7 +956,7 @@ class UserEmailConfirmView(FormView):
@transaction.atomic()
def form_valid(self, form):
reason = self.request.GET.get('reason')
reason = self.request.GET['reason']
if reason not in ('email_change', 'email_verify'):
raise PermissionDenied
try:
-23
View File
@@ -40,7 +40,6 @@ from django.utils.functional import cached_property
from django.utils.translation import gettext_lazy as _
from django.views import View
from django.views.generic import ListView, TemplateView
from django_otp import devices_for_user
from django_otp.plugins.otp_static.models import StaticDevice
from hijack import signals
@@ -108,9 +107,6 @@ class UserEditView(AdministratorPermissionRequiredMixin, RecentAuthenticationReq
ctx['backend'] = (
b[self.object.auth_backend].verbose_name if self.object.auth_backend in b else self.object.auth_backend
)
ctx['devices'] = devices_for_user(self.object)
return ctx
def get_success_url(self):
@@ -187,25 +183,6 @@ class UserEmergencyTokenView(AdministratorPermissionRequiredMixin, RecentAuthent
return reverse('control:users.edit', kwargs=self.kwargs)
class Reset2FADriftThrottleView(AdministratorPermissionRequiredMixin, RecentAuthenticationRequiredMixin, View):
def get(self, request, *args, **kwargs):
return redirect(reverse('control:users.edit', kwargs=self.kwargs))
def post(self, request, *args, **kwargs):
self.object = get_object_or_404(User, pk=self.kwargs.get("id"))
self.object.totpdevice_set.update(drift=0, throttling_failure_timestamp=None, throttling_failure_count=0)
self.object.staticdevice_set.update(throttling_failure_timestamp=None, throttling_failure_count=0)
self.object.log_action('pretix.user.settings.2fa.resetdrift', user=self.request.user)
messages.success(request, _(
'The drift values for TOTP devices have been reset.'
))
return redirect(self.get_success_url())
def get_success_url(self):
return reverse('control:users.edit', kwargs=self.kwargs)
class UserAnonymizeView(AdministratorPermissionRequiredMixin, RecentAuthenticationRequiredMixin, TemplateView):
template_name = "pretixcontrol/users/anonymize.html"
+2 -4
View File
@@ -144,7 +144,7 @@ class VoucherList(VoucherQueryMixin, PaginationMixin, EventPermissionRequiredMix
headers = [
_('Voucher code'), _('Valid until'), _('Product'), _('Reserve quota'), _('Bypass quota'),
_('Price effect'), _('Value'), _('Tag'), _('Redeemed'), _('Maximum usages'), _('Seat'),
_('Comment'), _('Budget'), _('Budget used')
_('Comment')
]
writer.writerow(headers)
@@ -170,9 +170,7 @@ class VoucherList(VoucherQueryMixin, PaginationMixin, EventPermissionRequiredMix
str(v.redeemed),
str(v.max_usages),
str(v.seat) if v.seat else "",
str(v.comment) if v.comment else "",
str(v.budget) if v.budget is not None else "",
str(v.budget_used) if v.budget is not None else "",
str(v.comment) if v.comment else ""
]
writer.writerow(row)
+21
View File
@@ -20,6 +20,8 @@
# <https://www.gnu.org/licenses/>.
#
import contextlib
import logging
import os
from django.conf import settings
from django.contrib.postgres.indexes import BrinIndex
@@ -30,6 +32,8 @@ from django.db.models import (
)
from django.utils.functional import lazy
logger = logging.getLogger(__name__)
class DummyRollbackException(Exception):
pass
@@ -288,6 +292,23 @@ def get_deterministic_ordering(model, ordering):
return ordering
@contextlib.contextmanager
def ensure_no_queries():
"""
Ensures that no database queries are being made in that context.
Raises a RuntimeError if running in DEBUG mode, otherwise logs
an error.
:return:
"""
def blocker(*args, **kwargs):
if settings.DEBUG or "PYTEST_CURRENT_TEST" in os.environ and "ENSURE_NO_QUERIES_OVERRIDE" not in os.environ:
raise RuntimeError(f"Unexpected DB query: {args[1]}")
logger.error("Unexpected DB query: %s", args[1])
with connection.execute_wrapper(blocker):
yield
@contextlib.contextmanager
def conditional_atomic(do_atomic, **kwargs):
if do_atomic:
-18
View File
@@ -27,7 +27,6 @@ from http import cookies
from django.conf import settings
from django.core.exceptions import SuspiciousFileOperation
from django.middleware.csrf import CsrfViewMiddleware as BaseCsrfMiddleware
from PIL import Image
from requests.adapters import HTTPAdapter
from urllib3.connection import HTTPConnection, HTTPSConnection
@@ -43,7 +42,6 @@ from urllib3.util.timeout import _DEFAULT_TIMEOUT
from pretix.helpers.reportlab import ThumbnailingImageReader
from pretix.helpers.ssrf import should_block_access
from pretix.multidomain.middlewares import CsrfViewMiddleware
def monkeypatch_vobject_performance():
@@ -244,20 +242,6 @@ def monkeypatch_reportlab_imagereader():
utils.ImageReader.__init__ = new_init
def monkeypatch_csrf_middleware():
# Some views from django or plugins use the middleware or the derived decorators directly,
# so we have to also patch the stock middleware
BaseCsrfMiddleware._get_secret = CsrfViewMiddleware._get_secret
BaseCsrfMiddleware._set_csrf_cookie = CsrfViewMiddleware._set_csrf_cookie
def monkeypatch_json_constants():
from json.decoder import _CONSTANTS # noqa
del _CONSTANTS['-Infinity']
del _CONSTANTS['Infinity']
del _CONSTANTS['NaN']
def monkeypatch_all_at_ready():
monkeypatch_vobject_performance()
monkeypatch_pillow_safer()
@@ -265,5 +249,3 @@ def monkeypatch_all_at_ready():
monkeypatch_urllib3_ssrf_protection()
monkeypatch_cookie_morsel()
monkeypatch_reportlab_imagereader()
monkeypatch_csrf_middleware()
monkeypatch_json_constants()
+1 -1
View File
@@ -29,7 +29,7 @@ from django.urls import reverse
def build_absolute_uri(urlname, args=None, kwargs=None):
warnings.warn(
'Usage of build_absolute_uri is confusing since there are many functions with that name. '
'Replace this usage with mainreverse_absolute.',
'Replace this usage with ',
DeprecationWarning
)
return mainreverse_absolute(urlname, args, kwargs)
+274 -346
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-30 07:26+0000\n"
"POT-Creation-Date: 2026-08-24 15:35+0000\n"
"PO-Revision-Date: 2026-07-15 14:20+0000\n"
"Last-Translator: Llewelyn Barkhuizen <llewelyn@akademia.ac.za>\n"
"Language-Team: Afrikaans <https://translate.pretix.eu/projects/pretix/pretix/"
@@ -198,7 +198,7 @@ msgid "Allowed Post Logout URIs list, space separated"
msgstr ""
#: pretix/api/models.py pretix/base/models/customers.py
#: pretix/plugins/paypal2/payment.py
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid "Client ID"
msgstr ""
@@ -1718,18 +1718,6 @@ msgstr ""
msgid "Payment providers"
msgstr ""
#: pretix/base/exporters/invoices.py pretix/base/models/orders.py
msgid "Transmission type"
msgstr ""
#: pretix/base/exporters/invoices.py
msgid "Transmission status"
msgstr ""
#: pretix/base/exporters/invoices.py
msgid "Transmission date"
msgstr ""
#: pretix/base/exporters/invoices.py
msgid "Cancellation"
msgstr ""
@@ -2373,6 +2361,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/organizers/giftcard.html
#: pretix/plugins/banktransfer/refund_export.py
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/import_form.html
#: pretix/plugins/paypal/templates/pretixplugins/paypal/control.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control_legacy.html
#: pretix/plugins/stripe/templates/pretixplugins/stripe/control.html
@@ -2396,6 +2385,7 @@ msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
msgid "Quantity"
msgstr ""
@@ -2477,6 +2467,7 @@ msgstr ""
#: pretix/base/exporters/orderlist.py
#: pretix/control/templates/pretixcontrol/search/payments.html
#: pretix/plugins/paypal/templates/pretixplugins/paypal/control.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control_legacy.html
msgid "Payment ID"
msgstr ""
@@ -4234,10 +4225,6 @@ msgstr ""
msgid "Initialization date"
msgstr ""
#: pretix/base/models/devices.py
msgid "Security profile"
msgstr ""
#: pretix/base/models/discount.py
msgctxt "subevent"
msgid "Dates can be mixed without limitation"
@@ -5453,10 +5440,6 @@ msgstr ""
msgid "Maximum value"
msgstr ""
#: pretix/base/models/items.py
msgid "Minimum length"
msgstr ""
#: pretix/base/models/items.py
msgid "Maximum length"
msgstr ""
@@ -5523,10 +5506,6 @@ msgstr ""
msgid "The maximum value must not be lower than the minimum value."
msgstr ""
#: pretix/base/models/items.py
msgid "The maximum length must not be shorter than the minimum length."
msgstr ""
#: pretix/base/models/items.py
msgid ""
"The system already contains answers to this question that are not compatible "
@@ -6020,6 +5999,10 @@ msgstr ""
msgid "This reference will be printed on your invoice for your convenience."
msgstr ""
#: pretix/base/models/orders.py
msgid "Transmission type"
msgstr ""
#: pretix/base/models/orders.py
#: pretix/plugins/badges/templates/pretixplugins/badges/control_order_position_buttons.html
msgid "Badge"
@@ -9493,17 +9476,6 @@ msgid ""
"'Last date of payments' configured above."
msgstr ""
#: pretix/base/settings.py
msgid "Allow postponed payment choice for sales channels"
msgstr ""
#: pretix/base/settings.py
msgid ""
"If postponed payment is allowed on a sales channel, customers can complete "
"their order without selecting a payment method. This is useful whenever "
"orders are not created by the same person who is making the payment."
msgstr ""
#: pretix/base/settings.py
msgid "Show start date"
msgstr ""
@@ -10025,6 +9997,12 @@ msgstr ""
msgid "Hide all unavailable dates from calendar or list views"
msgstr ""
#: pretix/base/settings.py
msgid ""
"This option currently only affects the calendar of this event series, not "
"the organizer-wide calendar."
msgstr ""
#: pretix/base/settings.py
msgid "Hide all past dates from calendar"
msgstr ""
@@ -14713,11 +14691,6 @@ msgctxt "rrule"
msgid "third"
msgstr ""
#: pretix/control/forms/rrule.py
msgctxt "rrule"
msgid "fourth"
msgstr ""
#: pretix/control/forms/rrule.py
msgctxt "rrule"
msgid "last"
@@ -15701,22 +15674,6 @@ msgstr ""
msgid "Queued emails have been aborted."
msgstr ""
#: pretix/control/logdisplay.py
msgid "An organizer meta property has been created."
msgstr ""
#: pretix/control/logdisplay.py
msgid "An organizer meta property has been deleted."
msgstr ""
#: pretix/control/logdisplay.py
msgid "An organizer meta property has been changed."
msgstr ""
#: pretix/control/logdisplay.py
msgid "An organizer meta property has been reordered."
msgstr ""
#: pretix/control/logdisplay.py
msgid "Gift card acceptance for another organizer has been added."
msgstr ""
@@ -15919,10 +15876,6 @@ msgstr ""
msgid "A two-factor emergency code has been generated."
msgstr ""
#: pretix/control/logdisplay.py
msgid "Drift and throttle values for two-factor devices have been reset."
msgstr ""
#: pretix/control/logdisplay.py
#, python-brace-format
msgid ""
@@ -16755,87 +16708,6 @@ msgid ""
"Granting access to your pretix account happens at your own risk."
msgstr ""
#: pretix/control/templates/pretixcontrol/auth/oauth_authorization.html
#: pretix/control/templates/pretixcontrol/checkin/bulk_revert_confirm.html
#: pretix/control/templates/pretixcontrol/checkin/list_delete.html
#: pretix/control/templates/pretixcontrol/checkin/reset.html
#: pretix/control/templates/pretixcontrol/datasync/control_order_info.html
#: pretix/control/templates/pretixcontrol/email_setup_simple.html
#: pretix/control/templates/pretixcontrol/event/tax_delete.html
#: pretix/control/templates/pretixcontrol/item/delete.html
#: pretix/control/templates/pretixcontrol/items/category_delete.html
#: pretix/control/templates/pretixcontrol/items/discount_delete.html
#: pretix/control/templates/pretixcontrol/items/question_delete.html
#: pretix/control/templates/pretixcontrol/items/quota_delete.html
#: pretix/control/templates/pretixcontrol/items/quota_delete_bulk.html
#: pretix/control/templates/pretixcontrol/oauth/app_delete.html
#: pretix/control/templates/pretixcontrol/oauth/app_rollkeys.html
#: pretix/control/templates/pretixcontrol/oauth/auth_revoke.html
#: pretix/control/templates/pretixcontrol/order/change.html
#: pretix/control/templates/pretixcontrol/order/change_contact.html
#: pretix/control/templates/pretixcontrol/order/change_locale.html
#: pretix/control/templates/pretixcontrol/order/change_questions.html
#: pretix/control/templates/pretixcontrol/order/extend.html
#: pretix/control/templates/pretixcontrol/order/pay.html
#: pretix/control/templates/pretixcontrol/order/pay_complete.html
#: pretix/control/templates/pretixcontrol/order/reactivate.html
#: pretix/control/templates/pretixcontrol/order/refund_choose.html
#: pretix/control/templates/pretixcontrol/order/refund_done.html
#: pretix/control/templates/pretixcontrol/order/refund_process.html
#: pretix/control/templates/pretixcontrol/order/refund_start.html
#: pretix/control/templates/pretixcontrol/orders/bulk_action.html
#: pretix/control/templates/pretixcontrol/orders/export_delete.html
#: pretix/control/templates/pretixcontrol/orders/refunds.html
#: pretix/control/templates/pretixcontrol/organizers/channel_delete.html
#: pretix/control/templates/pretixcontrol/organizers/customer_anonymize.html
#: pretix/control/templates/pretixcontrol/organizers/customer_membership_delete.html
#: pretix/control/templates/pretixcontrol/organizers/device_revoke.html
#: pretix/control/templates/pretixcontrol/organizers/export_delete.html
#: pretix/control/templates/pretixcontrol/organizers/gate_delete.html
#: pretix/control/templates/pretixcontrol/organizers/membershiptype_delete.html
#: pretix/control/templates/pretixcontrol/organizers/property_delete.html
#: pretix/control/templates/pretixcontrol/organizers/ssoclient_delete.html
#: pretix/control/templates/pretixcontrol/organizers/ssoprovider_delete.html
#: pretix/control/templates/pretixcontrol/organizers/team_delete.html
#: pretix/control/templates/pretixcontrol/pdf/index.html
#: pretix/control/templates/pretixcontrol/subevents/bulk_edit.html
#: pretix/control/templates/pretixcontrol/subevents/delete.html
#: pretix/control/templates/pretixcontrol/subevents/delete_bulk.html
#: pretix/control/templates/pretixcontrol/subevents/edit.html
#: pretix/control/templates/pretixcontrol/user/2fa_delete.html
#: pretix/control/templates/pretixcontrol/user/2fa_disable.html
#: pretix/control/templates/pretixcontrol/user/2fa_enable.html
#: pretix/control/templates/pretixcontrol/user/2fa_leaveteams.html
#: pretix/control/templates/pretixcontrol/user/2fa_regenemergency.html
#: pretix/control/templates/pretixcontrol/user/change_email.html
#: pretix/control/templates/pretixcontrol/user/change_password.html
#: pretix/control/templates/pretixcontrol/user/confirmation_code_dialog.html
#: pretix/control/templates/pretixcontrol/vouchers/delete.html
#: pretix/control/templates/pretixcontrol/vouchers/delete_bulk.html
#: pretix/control/templates/pretixcontrol/vouchers/delete_carts.html
#: pretix/control/templates/pretixcontrol/waitinglist/delete.html
#: pretix/control/templates/pretixcontrol/waitinglist/delete_bulk.html
#: pretix/control/templates/pretixcontrol/waitinglist/edit.html
#: pretix/plugins/autocheckin/templates/pretixplugins/autocheckin/delete.html
#: pretix/plugins/badges/templates/pretixplugins/badges/delete.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/pay.html
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_delete.html
#: pretix/plugins/stripe/templates/pretixplugins/stripe/sca.html
#: pretix/plugins/ticketoutputpdf/templates/pretixplugins/ticketoutputpdf/delete.html
#: pretix/presale/templates/pretixpresale/event/order_change.html
#: pretix/presale/templates/pretixpresale/event/order_modify.html
#: pretix/presale/templates/pretixpresale/event/order_pay.html
#: pretix/presale/templates/pretixpresale/event/order_pay_change.html
#: pretix/presale/templates/pretixpresale/event/order_pay_confirm.html
#: pretix/presale/templates/pretixpresale/event/position_change.html
#: pretix/presale/templates/pretixpresale/event/position_modify.html
msgid "Cancel"
msgstr ""
#: pretix/control/templates/pretixcontrol/auth/oauth_authorization.html
msgid "Authorize"
msgstr ""
#: pretix/control/templates/pretixcontrol/auth/oauth_authorization.html
msgid "Error:"
msgstr ""
@@ -17197,6 +17069,82 @@ msgid_plural ""
msgstr[0] ""
msgstr[1] ""
#: pretix/control/templates/pretixcontrol/checkin/bulk_revert_confirm.html
#: pretix/control/templates/pretixcontrol/checkin/list_delete.html
#: pretix/control/templates/pretixcontrol/checkin/reset.html
#: pretix/control/templates/pretixcontrol/datasync/control_order_info.html
#: pretix/control/templates/pretixcontrol/email_setup_simple.html
#: pretix/control/templates/pretixcontrol/event/tax_delete.html
#: pretix/control/templates/pretixcontrol/item/delete.html
#: pretix/control/templates/pretixcontrol/items/category_delete.html
#: pretix/control/templates/pretixcontrol/items/discount_delete.html
#: pretix/control/templates/pretixcontrol/items/question_delete.html
#: pretix/control/templates/pretixcontrol/items/quota_delete.html
#: pretix/control/templates/pretixcontrol/items/quota_delete_bulk.html
#: pretix/control/templates/pretixcontrol/oauth/app_delete.html
#: pretix/control/templates/pretixcontrol/oauth/app_rollkeys.html
#: pretix/control/templates/pretixcontrol/oauth/auth_revoke.html
#: pretix/control/templates/pretixcontrol/order/change.html
#: pretix/control/templates/pretixcontrol/order/change_contact.html
#: pretix/control/templates/pretixcontrol/order/change_locale.html
#: pretix/control/templates/pretixcontrol/order/change_questions.html
#: pretix/control/templates/pretixcontrol/order/extend.html
#: pretix/control/templates/pretixcontrol/order/pay.html
#: pretix/control/templates/pretixcontrol/order/pay_complete.html
#: pretix/control/templates/pretixcontrol/order/reactivate.html
#: pretix/control/templates/pretixcontrol/order/refund_choose.html
#: pretix/control/templates/pretixcontrol/order/refund_done.html
#: pretix/control/templates/pretixcontrol/order/refund_process.html
#: pretix/control/templates/pretixcontrol/order/refund_start.html
#: pretix/control/templates/pretixcontrol/orders/bulk_action.html
#: pretix/control/templates/pretixcontrol/orders/export_delete.html
#: pretix/control/templates/pretixcontrol/orders/refunds.html
#: pretix/control/templates/pretixcontrol/organizers/channel_delete.html
#: pretix/control/templates/pretixcontrol/organizers/customer_anonymize.html
#: pretix/control/templates/pretixcontrol/organizers/customer_membership_delete.html
#: pretix/control/templates/pretixcontrol/organizers/device_revoke.html
#: pretix/control/templates/pretixcontrol/organizers/export_delete.html
#: pretix/control/templates/pretixcontrol/organizers/gate_delete.html
#: pretix/control/templates/pretixcontrol/organizers/membershiptype_delete.html
#: pretix/control/templates/pretixcontrol/organizers/property_delete.html
#: pretix/control/templates/pretixcontrol/organizers/ssoclient_delete.html
#: pretix/control/templates/pretixcontrol/organizers/ssoprovider_delete.html
#: pretix/control/templates/pretixcontrol/organizers/team_delete.html
#: pretix/control/templates/pretixcontrol/pdf/index.html
#: pretix/control/templates/pretixcontrol/subevents/bulk_edit.html
#: pretix/control/templates/pretixcontrol/subevents/delete.html
#: pretix/control/templates/pretixcontrol/subevents/delete_bulk.html
#: pretix/control/templates/pretixcontrol/subevents/edit.html
#: pretix/control/templates/pretixcontrol/user/2fa_delete.html
#: pretix/control/templates/pretixcontrol/user/2fa_disable.html
#: pretix/control/templates/pretixcontrol/user/2fa_enable.html
#: pretix/control/templates/pretixcontrol/user/2fa_leaveteams.html
#: pretix/control/templates/pretixcontrol/user/2fa_regenemergency.html
#: pretix/control/templates/pretixcontrol/user/change_email.html
#: pretix/control/templates/pretixcontrol/user/change_password.html
#: pretix/control/templates/pretixcontrol/user/confirmation_code_dialog.html
#: pretix/control/templates/pretixcontrol/vouchers/delete.html
#: pretix/control/templates/pretixcontrol/vouchers/delete_bulk.html
#: pretix/control/templates/pretixcontrol/vouchers/delete_carts.html
#: pretix/control/templates/pretixcontrol/waitinglist/delete.html
#: pretix/control/templates/pretixcontrol/waitinglist/delete_bulk.html
#: pretix/control/templates/pretixcontrol/waitinglist/edit.html
#: pretix/plugins/autocheckin/templates/pretixplugins/autocheckin/delete.html
#: pretix/plugins/badges/templates/pretixplugins/badges/delete.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/pay.html
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_delete.html
#: pretix/plugins/stripe/templates/pretixplugins/stripe/sca.html
#: pretix/plugins/ticketoutputpdf/templates/pretixplugins/ticketoutputpdf/delete.html
#: pretix/presale/templates/pretixpresale/event/order_change.html
#: pretix/presale/templates/pretixpresale/event/order_modify.html
#: pretix/presale/templates/pretixpresale/event/order_pay.html
#: pretix/presale/templates/pretixpresale/event/order_pay_change.html
#: pretix/presale/templates/pretixpresale/event/order_pay_confirm.html
#: pretix/presale/templates/pretixpresale/event/position_change.html
#: pretix/presale/templates/pretixpresale/event/position_modify.html
msgid "Cancel"
msgstr ""
#: pretix/control/templates/pretixcontrol/checkin/bulk_revert_confirm.html
#: pretix/control/templates/pretixcontrol/checkin/list_delete.html
#: pretix/control/templates/pretixcontrol/event/delete.html
@@ -19308,7 +19256,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/events/create_basics.html
msgid ""
"We strongly recommend against using short forms of more than 16 characters."
"We strongly recommend against using short forms of more then 16 characters."
msgstr ""
#: pretix/control/templates/pretixcontrol/events/create_basics.html
@@ -24248,7 +24196,6 @@ msgid "Add a new device"
msgstr ""
#: pretix/control/templates/pretixcontrol/user/2fa_main.html
#: pretix/control/templates/pretixcontrol/users/form.html
msgid "Emergency tokens"
msgstr ""
@@ -24493,26 +24440,6 @@ msgstr ""
msgid "Authentication backend"
msgstr ""
#: pretix/control/templates/pretixcontrol/users/form.html
msgid "Reset drift and throttle"
msgstr ""
#: pretix/control/templates/pretixcontrol/users/form.html
msgid "Available two-factor authentication methods"
msgstr ""
#: pretix/control/templates/pretixcontrol/users/form.html
#, python-format
msgid "1 failed attempt since %(date)s"
msgid_plural "%(cnt)s failed attempts since %(date)s"
msgstr[0] ""
msgstr[1] ""
#: pretix/control/templates/pretixcontrol/users/form.html
#, python-format
msgid "Currently locked until %(date)s"
msgstr ""
#: pretix/control/templates/pretixcontrol/users/form.html
msgid "Team memberships"
msgstr ""
@@ -24966,20 +24893,6 @@ msgstr ""
msgid "Invalid code, please try again."
msgstr ""
#: pretix/control/views/auth.py
#, python-brace-format
msgid "Invalid code. Please try again after waiting {value} minute."
msgid_plural "Invalid code. Please try again after waiting {value} minutes."
msgstr[0] ""
msgstr[1] ""
#: pretix/control/views/auth.py
#, python-brace-format
msgid "Invalid code. Please try again after waiting {value} second."
msgid_plural "Invalid code. Please try again after waiting {value} seconds."
msgstr[0] ""
msgstr[1] ""
#: pretix/control/views/checkin.py
msgid "The selected check-ins have been reverted."
msgstr ""
@@ -25732,10 +25645,6 @@ msgstr ""
msgid "You entered an order in an event with a different currency."
msgstr ""
#: pretix/control/views/orders.py
msgid "You entered an order in an event that you do not have access to."
msgstr ""
#: pretix/control/views/orders.py
msgid ""
"You can not refund more than the amount of a payment that is not yet "
@@ -25748,10 +25657,6 @@ msgid ""
"refunds."
msgstr ""
#: pretix/control/views/orders.py
msgid "The refunds you selected do not match the selected total refund amount."
msgstr ""
#: pretix/control/views/orders.py
#, python-brace-format
msgid ""
@@ -25793,6 +25698,10 @@ msgid ""
"Your {event} team"
msgstr ""
#: pretix/control/views/orders.py
msgid "The refunds you selected do not match the selected total refund amount."
msgstr ""
#: pretix/control/views/orders.py
msgid "The payment has been created successfully."
msgstr ""
@@ -26504,10 +26413,6 @@ msgid ""
"remain active."
msgstr ""
#: pretix/control/views/users.py
msgid "The drift values for TOTP devices have been reset."
msgstr ""
#: pretix/control/views/users.py
msgid "The new user has been created."
msgstr ""
@@ -26520,14 +26425,6 @@ msgstr ""
msgid "Bypass quota"
msgstr ""
#: pretix/control/views/vouchers.py
msgid "Budget"
msgstr ""
#: pretix/control/views/vouchers.py
msgid "Budget used"
msgstr ""
#: pretix/control/views/vouchers.py
msgid "The requested voucher does not exist."
msgstr ""
@@ -26680,11 +26577,12 @@ msgstr ""
#: pretix/plugins/autocheckin/apps.py pretix/plugins/badges/apps.py
#: pretix/plugins/banktransfer/apps.py pretix/plugins/checkinlists/apps.py
#: pretix/plugins/manualpayment/apps.py pretix/plugins/paypal2/apps.py
#: pretix/plugins/pretixdroid/apps.py pretix/plugins/reports/apps.py
#: pretix/plugins/returnurl/apps.py pretix/plugins/sendmail/apps.py
#: pretix/plugins/statistics/apps.py pretix/plugins/stripe/apps.py
#: pretix/plugins/ticketoutputpdf/apps.py pretix/plugins/webcheckin/apps.py
#: pretix/plugins/manualpayment/apps.py pretix/plugins/paypal/apps.py
#: pretix/plugins/paypal2/apps.py pretix/plugins/pretixdroid/apps.py
#: pretix/plugins/reports/apps.py pretix/plugins/returnurl/apps.py
#: pretix/plugins/sendmail/apps.py pretix/plugins/statistics/apps.py
#: pretix/plugins/stripe/apps.py pretix/plugins/ticketoutputpdf/apps.py
#: pretix/plugins/webcheckin/apps.py
msgid "the pretix team"
msgstr ""
@@ -27235,6 +27133,7 @@ msgstr ""
#: pretix/plugins/banktransfer/refund_export.py
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/control.html
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/import_assign.html
#: pretix/plugins/paypal/templates/pretixplugins/paypal/control.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control_legacy.html
msgid "Payer"
@@ -27728,7 +27627,8 @@ msgstr ""
msgid "Automatically checked in"
msgstr ""
#: pretix/plugins/checkinlists/exporters.py pretix/plugins/paypal2/payment.py
#: pretix/plugins/checkinlists/exporters.py pretix/plugins/paypal/payment.py
#: pretix/plugins/paypal2/payment.py
msgid "Secret"
msgstr ""
@@ -27787,6 +27687,152 @@ msgstr ""
msgid "A fully customizable payment method for manual processing."
msgstr ""
#: pretix/plugins/paypal/apps.py pretix/plugins/paypal/payment.py
#: pretix/plugins/paypal2/apps.py pretix/plugins/paypal2/payment.py
#: pretix/plugins/stripe/payment.py
msgid "PayPal"
msgstr ""
#: pretix/plugins/paypal/apps.py
msgid ""
"Accept payments with your PayPal account. PayPal is one of the most popular "
"payment methods world-wide."
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid ""
"The PayPal sandbox is being used, you can test without actually sending "
"money but you will need a PayPal sandbox user to log in."
msgstr ""
#: pretix/plugins/paypal/payment.py
msgid "PayPal account"
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid "Click here for a tutorial on how to obtain the required keys"
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
#: pretix/plugins/stripe/payment.py
msgid "Endpoint"
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid "Reference prefix"
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid ""
"Any value entered here will be added in front of the regular booking "
"reference containing the order number."
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid "Reference postfix"
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid ""
"Any value entered here will be added behind the regular booking reference "
"containing the order number."
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid "Disconnect from PayPal"
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid "We had trouble communicating with PayPal"
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid ""
"We were unable to process your payment. See below for details on how to "
"proceed."
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid ""
"PayPal has not yet approved the payment. We will inform you as soon as the "
"payment completed."
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
#, python-brace-format
msgid "Refunding the amount via PayPal failed: {}"
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid "The payment for this invoice has already been received."
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid "PayPal payment ID"
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid "PayPal sale ID"
msgstr ""
#: pretix/plugins/paypal/templates/pretixplugins/paypal/checkout_payment_confirm.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/checkout_payment_confirm.html
msgid ""
"The total amount listed above will be withdrawn from your PayPal account "
"after the confirmation of your purchase."
msgstr ""
#: pretix/plugins/paypal/templates/pretixplugins/paypal/checkout_payment_form.html
msgid ""
"After you clicked continue, we will redirect you to PayPal to fill in your "
"payment details. You will then be redirected back here to review and confirm "
"your order."
msgstr ""
#: pretix/plugins/paypal/templates/pretixplugins/paypal/control.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control_legacy.html
msgid "Sale ID"
msgstr ""
#: pretix/plugins/paypal/templates/pretixplugins/paypal/control.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control_legacy.html
msgid "Last update"
msgstr ""
#: pretix/plugins/paypal/templates/pretixplugins/paypal/control.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control_legacy.html
#: pretix/plugins/stripe/templates/pretixplugins/stripe/control.html
msgid "Total value"
msgstr ""
#: pretix/plugins/paypal/templates/pretixplugins/paypal/pending.html
msgid ""
"Our attempt to execute your Payment via PayPal has failed. Please try again "
"or contact us."
msgstr ""
#: pretix/plugins/paypal/templates/pretixplugins/paypal/pending.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/pending.html
msgid ""
"We're waiting for an answer from PayPal regarding your payment. Please "
"contact us, if this takes more than a few hours."
msgstr ""
#: pretix/plugins/paypal/views.py pretix/plugins/paypal2/views.py
msgid "Invalid response from PayPal received."
msgstr ""
#: pretix/plugins/paypal/views.py pretix/plugins/paypal2/views.py
msgid "It looks like you canceled the PayPal payment"
msgstr ""
#: pretix/plugins/paypal/views.py pretix/plugins/paypal2/views.py
msgid "Your PayPal account has been disconnected."
msgstr ""
#: pretix/plugins/paypal2/apps.py
msgid ""
"Accept payments with your PayPal account. In addition to regular PayPal "
@@ -27796,23 +27842,10 @@ msgid ""
"methods world-wide."
msgstr ""
#: pretix/plugins/paypal2/apps.py pretix/plugins/paypal2/payment.py
#: pretix/plugins/stripe/payment.py
msgid "PayPal"
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid "PayPal Merchant ID"
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid "Click here for a tutorial on how to obtain the required keys"
msgstr ""
#: pretix/plugins/paypal2/payment.py pretix/plugins/stripe/payment.py
msgid "Endpoint"
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid ""
"Even if a customer chooses an Alternative Payment Method, they will always "
@@ -27881,26 +27914,6 @@ msgid ""
"while the last payment is still under investigation."
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid "Reference prefix"
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid ""
"Any value entered here will be added in front of the regular booking "
"reference containing the order number."
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid "Reference postfix"
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid ""
"Any value entered here will be added behind the regular booking reference "
"containing the order number."
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid "-- Automatic --"
msgstr ""
@@ -27921,10 +27934,6 @@ msgstr ""
msgid "Connect with {icon} PayPal"
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid "Disconnect from PayPal"
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid ""
"Please configure a PayPal Webhook to the following endpoint in order to "
@@ -27953,12 +27962,6 @@ msgstr ""
msgid "An error occurred during connecting with PayPal, please try again."
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid ""
"The PayPal sandbox is being used, you can test without actually sending "
"money but you will need a PayPal sandbox user to log in."
msgstr ""
#: pretix/plugins/paypal2/payment.py
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/pending.html
msgid ""
@@ -27967,10 +27970,6 @@ msgid ""
"attempt. You can also try other payment methods, if available."
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid "We had trouble communicating with PayPal"
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid ""
"Something went wrong when requesting the payment status. Please try again."
@@ -27980,41 +27979,12 @@ msgstr ""
msgid "You may need to enable JavaScript for PayPal payments."
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid ""
"We were unable to process your payment. See below for details on how to "
"proceed."
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid ""
"PayPal has not yet approved the payment. We will inform you as soon as the "
"payment completed."
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid ""
"Refunding the amount via PayPal failed: The original payment does not "
"contain the required information to issue an automated refund."
msgstr ""
#: pretix/plugins/paypal2/payment.py
#, python-brace-format
msgid "Refunding the amount via PayPal failed: {}"
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid "The payment for this invoice has already been received."
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid "PayPal payment ID"
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid "PayPal sale ID"
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid "PayPal APM"
msgstr ""
@@ -28102,12 +28072,6 @@ msgstr ""
msgid "We will then charge your PayPal account and finalize the order."
msgstr ""
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/checkout_payment_confirm.html
msgid ""
"The total amount listed above will be withdrawn from your PayPal account "
"after the confirmation of your purchase."
msgstr ""
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/checkout_payment_confirm.html
msgid ""
"After placing your order, you will be able to select your desired payment "
@@ -28139,11 +28103,6 @@ msgid ""
"different payment method, if you prefer."
msgstr ""
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control_legacy.html
msgid "Sale ID"
msgstr ""
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control.html
msgid "Capture status"
msgstr ""
@@ -28154,17 +28113,6 @@ msgid ""
"money will not be disbursed and the order remain in its pending state."
msgstr ""
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control_legacy.html
msgid "Last update"
msgstr ""
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control_legacy.html
#: pretix/plugins/stripe/templates/pretixplugins/stripe/control.html
msgid "Total value"
msgstr ""
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/pay.html
#: pretix/plugins/stripe/templates/pretixplugins/stripe/sca.html
#: pretix/plugins/stripe/templates/pretixplugins/stripe/sca_return.html
@@ -28198,12 +28146,6 @@ msgid ""
"to resolve this case."
msgstr ""
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/pending.html
msgid ""
"We're waiting for an answer from PayPal regarding your payment. Please "
"contact us, if this takes more than a few hours."
msgstr ""
#: pretix/plugins/paypal2/views.py
msgid ""
"An error occurred returning from PayPal: request parameters missing. Please "
@@ -28234,18 +28176,6 @@ msgid ""
"in detail below."
msgstr ""
#: pretix/plugins/paypal2/views.py
msgid "Invalid response from PayPal received."
msgstr ""
#: pretix/plugins/paypal2/views.py
msgid "It looks like you canceled the PayPal payment"
msgstr ""
#: pretix/plugins/paypal2/views.py
msgid "Your PayPal account has been disconnected."
msgstr ""
#: pretix/plugins/pretixdroid/apps.py
msgid "Old check-in device API"
msgstr ""
@@ -30265,6 +30195,7 @@ msgstr ""
#: pretix/presale/forms/order.py
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
msgid "plus taxes"
msgstr ""
@@ -30685,31 +30616,6 @@ msgid ""
"Please go to the payment settings and activate one or more payment providers."
msgstr ""
#: pretix/presale/templates/pretixpresale/event/checkout_payment.html
msgid ""
"Not sure yet? You can complete your order first and then select a payment "
"method later."
msgstr ""
#: pretix/presale/templates/pretixpresale/event/checkout_payment.html
msgid ""
"To do so, please first remove the payment methods you already selected above."
msgstr ""
#: pretix/presale/templates/pretixpresale/event/checkout_payment.html
#, python-format
msgid "Your payment needs to be completed within %(minutes)s minutes."
msgstr ""
#: pretix/presale/templates/pretixpresale/event/checkout_payment.html
#, python-format
msgid "Your payment needs to be completed by %(deadline)s."
msgstr ""
#: pretix/presale/templates/pretixpresale/event/checkout_payment.html
msgid "Proceed without selection"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/checkout_questions.html
msgid "Before we continue, we need you to answer some questions."
msgstr ""
@@ -30776,12 +30682,14 @@ msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
#, python-format
msgid "minimum amount to order: %(num)s"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
msgctxt "price"
msgid "free"
msgstr ""
@@ -30810,56 +30718,66 @@ msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
msgid "Original price:"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
msgid "New price:"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
#, python-format
msgid "Modify price for %(item)s, at least %(price)s"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
#, python-format
msgid "Modify price for %(item)s"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
msgid "incl. taxes"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
#, python-format
msgid "<strong>plus</strong> %(rate)s%% %(name)s"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
#, python-format
msgid "incl. %(rate)s%% %(name)s"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
msgctxt "checkbox"
msgid "Select"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
msgid "Decrease quantity"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
msgid "Increase quantity"
msgstr ""
@@ -31320,10 +31238,12 @@ msgid "Your order qualifies for a discount"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
msgid "Uncategorized items"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
#, python-format
msgid "Show full-size image of %(item)s"
msgstr ""
@@ -31336,16 +31256,19 @@ msgstr[0] ""
msgstr[1] ""
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
#, python-format
msgid "%(value)s incl. taxes"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
#, python-format
msgid "%(value)s without taxes"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
#, python-format
msgid "Set price in %(currency)s for %(item)s"
msgstr ""
@@ -32004,6 +31927,11 @@ msgid ""
"products at the specified price:"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/voucher.html
#, python-format
msgid "from %(minprice)s"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/voucher.html
#, python-format
msgid "You need to select at least %(number)s products."
+84 -1
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-30 07:26+0000\n"
"POT-Creation-Date: 2026-07-07 09:33+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
@@ -765,163 +765,194 @@ msgstr ""
msgid "Google Pay"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Quantity"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Decrease quantity"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Increase quantity"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Filter events by"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Filter"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Price"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "Original price: %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "New price: %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Select"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "Select %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "Select variant %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Sold out"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Buy"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Register"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Reserved"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "FREE"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "from %(currency)s %(price)s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "Image of %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "incl. %(rate)s% %(taxname)s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "plus %(rate)s% %(taxname)s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "incl. taxes"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "plus taxes"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "currently available: %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Only available with a voucher"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Not yet available"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Not available anymore"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Currently not available"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "minimum amount to order: %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Close ticket shop"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "The ticket shop could not be loaded."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid ""
@@ -929,21 +960,25 @@ msgid ""
"in a new tab to continue."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Open ticket shop"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Checkout"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "The cart could not be created. Please try again later"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid ""
@@ -951,11 +986,13 @@ msgid ""
"this ticket shop. Please click \"Continue\" to retry in a new tab."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Waiting list"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid ""
@@ -963,96 +1000,115 @@ msgid ""
"products, they will be added to your existing cart."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Resume checkout"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Redeem a voucher"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Redeem"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Voucher code"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Close"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Close checkout"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "You cannot cancel this operation. Please wait for loading to finish."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Continue"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Show variants"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Hide variants"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Choose a different event"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Choose a different date"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Back"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Next month"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Previous month"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Next week"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Previous week"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Open seat selection"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid ""
@@ -1061,111 +1117,138 @@ msgid ""
"again."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Load more"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Mo"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Tu"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "We"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Th"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Fr"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Sa"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Su"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Monday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Tuesday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Wednesday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Thursday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Friday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Saturday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Sunday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "January"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "February"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "March"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "April"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "May"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "June"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "July"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "August"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "September"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "October"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "November"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "December"
msgstr ""
+274 -346
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-30 07:26+0000\n"
"POT-Creation-Date: 2026-08-24 15:35+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
@@ -196,7 +196,7 @@ msgid "Allowed Post Logout URIs list, space separated"
msgstr ""
#: pretix/api/models.py pretix/base/models/customers.py
#: pretix/plugins/paypal2/payment.py
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid "Client ID"
msgstr ""
@@ -1716,18 +1716,6 @@ msgstr ""
msgid "Payment providers"
msgstr ""
#: pretix/base/exporters/invoices.py pretix/base/models/orders.py
msgid "Transmission type"
msgstr ""
#: pretix/base/exporters/invoices.py
msgid "Transmission status"
msgstr ""
#: pretix/base/exporters/invoices.py
msgid "Transmission date"
msgstr ""
#: pretix/base/exporters/invoices.py
msgid "Cancellation"
msgstr ""
@@ -2371,6 +2359,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/organizers/giftcard.html
#: pretix/plugins/banktransfer/refund_export.py
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/import_form.html
#: pretix/plugins/paypal/templates/pretixplugins/paypal/control.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control_legacy.html
#: pretix/plugins/stripe/templates/pretixplugins/stripe/control.html
@@ -2394,6 +2383,7 @@ msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
msgid "Quantity"
msgstr ""
@@ -2475,6 +2465,7 @@ msgstr ""
#: pretix/base/exporters/orderlist.py
#: pretix/control/templates/pretixcontrol/search/payments.html
#: pretix/plugins/paypal/templates/pretixplugins/paypal/control.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control_legacy.html
msgid "Payment ID"
msgstr ""
@@ -4232,10 +4223,6 @@ msgstr ""
msgid "Initialization date"
msgstr ""
#: pretix/base/models/devices.py
msgid "Security profile"
msgstr ""
#: pretix/base/models/discount.py
msgctxt "subevent"
msgid "Dates can be mixed without limitation"
@@ -5451,10 +5438,6 @@ msgstr ""
msgid "Maximum value"
msgstr ""
#: pretix/base/models/items.py
msgid "Minimum length"
msgstr ""
#: pretix/base/models/items.py
msgid "Maximum length"
msgstr ""
@@ -5521,10 +5504,6 @@ msgstr ""
msgid "The maximum value must not be lower than the minimum value."
msgstr ""
#: pretix/base/models/items.py
msgid "The maximum length must not be shorter than the minimum length."
msgstr ""
#: pretix/base/models/items.py
msgid ""
"The system already contains answers to this question that are not compatible "
@@ -6018,6 +5997,10 @@ msgstr ""
msgid "This reference will be printed on your invoice for your convenience."
msgstr ""
#: pretix/base/models/orders.py
msgid "Transmission type"
msgstr ""
#: pretix/base/models/orders.py
#: pretix/plugins/badges/templates/pretixplugins/badges/control_order_position_buttons.html
msgid "Badge"
@@ -9491,17 +9474,6 @@ msgid ""
"'Last date of payments' configured above."
msgstr ""
#: pretix/base/settings.py
msgid "Allow postponed payment choice for sales channels"
msgstr ""
#: pretix/base/settings.py
msgid ""
"If postponed payment is allowed on a sales channel, customers can complete "
"their order without selecting a payment method. This is useful whenever "
"orders are not created by the same person who is making the payment."
msgstr ""
#: pretix/base/settings.py
msgid "Show start date"
msgstr ""
@@ -10023,6 +9995,12 @@ msgstr ""
msgid "Hide all unavailable dates from calendar or list views"
msgstr ""
#: pretix/base/settings.py
msgid ""
"This option currently only affects the calendar of this event series, not "
"the organizer-wide calendar."
msgstr ""
#: pretix/base/settings.py
msgid "Hide all past dates from calendar"
msgstr ""
@@ -14711,11 +14689,6 @@ msgctxt "rrule"
msgid "third"
msgstr ""
#: pretix/control/forms/rrule.py
msgctxt "rrule"
msgid "fourth"
msgstr ""
#: pretix/control/forms/rrule.py
msgctxt "rrule"
msgid "last"
@@ -15699,22 +15672,6 @@ msgstr ""
msgid "Queued emails have been aborted."
msgstr ""
#: pretix/control/logdisplay.py
msgid "An organizer meta property has been created."
msgstr ""
#: pretix/control/logdisplay.py
msgid "An organizer meta property has been deleted."
msgstr ""
#: pretix/control/logdisplay.py
msgid "An organizer meta property has been changed."
msgstr ""
#: pretix/control/logdisplay.py
msgid "An organizer meta property has been reordered."
msgstr ""
#: pretix/control/logdisplay.py
msgid "Gift card acceptance for another organizer has been added."
msgstr ""
@@ -15917,10 +15874,6 @@ msgstr ""
msgid "A two-factor emergency code has been generated."
msgstr ""
#: pretix/control/logdisplay.py
msgid "Drift and throttle values for two-factor devices have been reset."
msgstr ""
#: pretix/control/logdisplay.py
#, python-brace-format
msgid ""
@@ -16753,87 +16706,6 @@ msgid ""
"Granting access to your pretix account happens at your own risk."
msgstr ""
#: pretix/control/templates/pretixcontrol/auth/oauth_authorization.html
#: pretix/control/templates/pretixcontrol/checkin/bulk_revert_confirm.html
#: pretix/control/templates/pretixcontrol/checkin/list_delete.html
#: pretix/control/templates/pretixcontrol/checkin/reset.html
#: pretix/control/templates/pretixcontrol/datasync/control_order_info.html
#: pretix/control/templates/pretixcontrol/email_setup_simple.html
#: pretix/control/templates/pretixcontrol/event/tax_delete.html
#: pretix/control/templates/pretixcontrol/item/delete.html
#: pretix/control/templates/pretixcontrol/items/category_delete.html
#: pretix/control/templates/pretixcontrol/items/discount_delete.html
#: pretix/control/templates/pretixcontrol/items/question_delete.html
#: pretix/control/templates/pretixcontrol/items/quota_delete.html
#: pretix/control/templates/pretixcontrol/items/quota_delete_bulk.html
#: pretix/control/templates/pretixcontrol/oauth/app_delete.html
#: pretix/control/templates/pretixcontrol/oauth/app_rollkeys.html
#: pretix/control/templates/pretixcontrol/oauth/auth_revoke.html
#: pretix/control/templates/pretixcontrol/order/change.html
#: pretix/control/templates/pretixcontrol/order/change_contact.html
#: pretix/control/templates/pretixcontrol/order/change_locale.html
#: pretix/control/templates/pretixcontrol/order/change_questions.html
#: pretix/control/templates/pretixcontrol/order/extend.html
#: pretix/control/templates/pretixcontrol/order/pay.html
#: pretix/control/templates/pretixcontrol/order/pay_complete.html
#: pretix/control/templates/pretixcontrol/order/reactivate.html
#: pretix/control/templates/pretixcontrol/order/refund_choose.html
#: pretix/control/templates/pretixcontrol/order/refund_done.html
#: pretix/control/templates/pretixcontrol/order/refund_process.html
#: pretix/control/templates/pretixcontrol/order/refund_start.html
#: pretix/control/templates/pretixcontrol/orders/bulk_action.html
#: pretix/control/templates/pretixcontrol/orders/export_delete.html
#: pretix/control/templates/pretixcontrol/orders/refunds.html
#: pretix/control/templates/pretixcontrol/organizers/channel_delete.html
#: pretix/control/templates/pretixcontrol/organizers/customer_anonymize.html
#: pretix/control/templates/pretixcontrol/organizers/customer_membership_delete.html
#: pretix/control/templates/pretixcontrol/organizers/device_revoke.html
#: pretix/control/templates/pretixcontrol/organizers/export_delete.html
#: pretix/control/templates/pretixcontrol/organizers/gate_delete.html
#: pretix/control/templates/pretixcontrol/organizers/membershiptype_delete.html
#: pretix/control/templates/pretixcontrol/organizers/property_delete.html
#: pretix/control/templates/pretixcontrol/organizers/ssoclient_delete.html
#: pretix/control/templates/pretixcontrol/organizers/ssoprovider_delete.html
#: pretix/control/templates/pretixcontrol/organizers/team_delete.html
#: pretix/control/templates/pretixcontrol/pdf/index.html
#: pretix/control/templates/pretixcontrol/subevents/bulk_edit.html
#: pretix/control/templates/pretixcontrol/subevents/delete.html
#: pretix/control/templates/pretixcontrol/subevents/delete_bulk.html
#: pretix/control/templates/pretixcontrol/subevents/edit.html
#: pretix/control/templates/pretixcontrol/user/2fa_delete.html
#: pretix/control/templates/pretixcontrol/user/2fa_disable.html
#: pretix/control/templates/pretixcontrol/user/2fa_enable.html
#: pretix/control/templates/pretixcontrol/user/2fa_leaveteams.html
#: pretix/control/templates/pretixcontrol/user/2fa_regenemergency.html
#: pretix/control/templates/pretixcontrol/user/change_email.html
#: pretix/control/templates/pretixcontrol/user/change_password.html
#: pretix/control/templates/pretixcontrol/user/confirmation_code_dialog.html
#: pretix/control/templates/pretixcontrol/vouchers/delete.html
#: pretix/control/templates/pretixcontrol/vouchers/delete_bulk.html
#: pretix/control/templates/pretixcontrol/vouchers/delete_carts.html
#: pretix/control/templates/pretixcontrol/waitinglist/delete.html
#: pretix/control/templates/pretixcontrol/waitinglist/delete_bulk.html
#: pretix/control/templates/pretixcontrol/waitinglist/edit.html
#: pretix/plugins/autocheckin/templates/pretixplugins/autocheckin/delete.html
#: pretix/plugins/badges/templates/pretixplugins/badges/delete.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/pay.html
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_delete.html
#: pretix/plugins/stripe/templates/pretixplugins/stripe/sca.html
#: pretix/plugins/ticketoutputpdf/templates/pretixplugins/ticketoutputpdf/delete.html
#: pretix/presale/templates/pretixpresale/event/order_change.html
#: pretix/presale/templates/pretixpresale/event/order_modify.html
#: pretix/presale/templates/pretixpresale/event/order_pay.html
#: pretix/presale/templates/pretixpresale/event/order_pay_change.html
#: pretix/presale/templates/pretixpresale/event/order_pay_confirm.html
#: pretix/presale/templates/pretixpresale/event/position_change.html
#: pretix/presale/templates/pretixpresale/event/position_modify.html
msgid "Cancel"
msgstr ""
#: pretix/control/templates/pretixcontrol/auth/oauth_authorization.html
msgid "Authorize"
msgstr ""
#: pretix/control/templates/pretixcontrol/auth/oauth_authorization.html
msgid "Error:"
msgstr ""
@@ -17195,6 +17067,82 @@ msgid_plural ""
msgstr[0] ""
msgstr[1] ""
#: pretix/control/templates/pretixcontrol/checkin/bulk_revert_confirm.html
#: pretix/control/templates/pretixcontrol/checkin/list_delete.html
#: pretix/control/templates/pretixcontrol/checkin/reset.html
#: pretix/control/templates/pretixcontrol/datasync/control_order_info.html
#: pretix/control/templates/pretixcontrol/email_setup_simple.html
#: pretix/control/templates/pretixcontrol/event/tax_delete.html
#: pretix/control/templates/pretixcontrol/item/delete.html
#: pretix/control/templates/pretixcontrol/items/category_delete.html
#: pretix/control/templates/pretixcontrol/items/discount_delete.html
#: pretix/control/templates/pretixcontrol/items/question_delete.html
#: pretix/control/templates/pretixcontrol/items/quota_delete.html
#: pretix/control/templates/pretixcontrol/items/quota_delete_bulk.html
#: pretix/control/templates/pretixcontrol/oauth/app_delete.html
#: pretix/control/templates/pretixcontrol/oauth/app_rollkeys.html
#: pretix/control/templates/pretixcontrol/oauth/auth_revoke.html
#: pretix/control/templates/pretixcontrol/order/change.html
#: pretix/control/templates/pretixcontrol/order/change_contact.html
#: pretix/control/templates/pretixcontrol/order/change_locale.html
#: pretix/control/templates/pretixcontrol/order/change_questions.html
#: pretix/control/templates/pretixcontrol/order/extend.html
#: pretix/control/templates/pretixcontrol/order/pay.html
#: pretix/control/templates/pretixcontrol/order/pay_complete.html
#: pretix/control/templates/pretixcontrol/order/reactivate.html
#: pretix/control/templates/pretixcontrol/order/refund_choose.html
#: pretix/control/templates/pretixcontrol/order/refund_done.html
#: pretix/control/templates/pretixcontrol/order/refund_process.html
#: pretix/control/templates/pretixcontrol/order/refund_start.html
#: pretix/control/templates/pretixcontrol/orders/bulk_action.html
#: pretix/control/templates/pretixcontrol/orders/export_delete.html
#: pretix/control/templates/pretixcontrol/orders/refunds.html
#: pretix/control/templates/pretixcontrol/organizers/channel_delete.html
#: pretix/control/templates/pretixcontrol/organizers/customer_anonymize.html
#: pretix/control/templates/pretixcontrol/organizers/customer_membership_delete.html
#: pretix/control/templates/pretixcontrol/organizers/device_revoke.html
#: pretix/control/templates/pretixcontrol/organizers/export_delete.html
#: pretix/control/templates/pretixcontrol/organizers/gate_delete.html
#: pretix/control/templates/pretixcontrol/organizers/membershiptype_delete.html
#: pretix/control/templates/pretixcontrol/organizers/property_delete.html
#: pretix/control/templates/pretixcontrol/organizers/ssoclient_delete.html
#: pretix/control/templates/pretixcontrol/organizers/ssoprovider_delete.html
#: pretix/control/templates/pretixcontrol/organizers/team_delete.html
#: pretix/control/templates/pretixcontrol/pdf/index.html
#: pretix/control/templates/pretixcontrol/subevents/bulk_edit.html
#: pretix/control/templates/pretixcontrol/subevents/delete.html
#: pretix/control/templates/pretixcontrol/subevents/delete_bulk.html
#: pretix/control/templates/pretixcontrol/subevents/edit.html
#: pretix/control/templates/pretixcontrol/user/2fa_delete.html
#: pretix/control/templates/pretixcontrol/user/2fa_disable.html
#: pretix/control/templates/pretixcontrol/user/2fa_enable.html
#: pretix/control/templates/pretixcontrol/user/2fa_leaveteams.html
#: pretix/control/templates/pretixcontrol/user/2fa_regenemergency.html
#: pretix/control/templates/pretixcontrol/user/change_email.html
#: pretix/control/templates/pretixcontrol/user/change_password.html
#: pretix/control/templates/pretixcontrol/user/confirmation_code_dialog.html
#: pretix/control/templates/pretixcontrol/vouchers/delete.html
#: pretix/control/templates/pretixcontrol/vouchers/delete_bulk.html
#: pretix/control/templates/pretixcontrol/vouchers/delete_carts.html
#: pretix/control/templates/pretixcontrol/waitinglist/delete.html
#: pretix/control/templates/pretixcontrol/waitinglist/delete_bulk.html
#: pretix/control/templates/pretixcontrol/waitinglist/edit.html
#: pretix/plugins/autocheckin/templates/pretixplugins/autocheckin/delete.html
#: pretix/plugins/badges/templates/pretixplugins/badges/delete.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/pay.html
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_delete.html
#: pretix/plugins/stripe/templates/pretixplugins/stripe/sca.html
#: pretix/plugins/ticketoutputpdf/templates/pretixplugins/ticketoutputpdf/delete.html
#: pretix/presale/templates/pretixpresale/event/order_change.html
#: pretix/presale/templates/pretixpresale/event/order_modify.html
#: pretix/presale/templates/pretixpresale/event/order_pay.html
#: pretix/presale/templates/pretixpresale/event/order_pay_change.html
#: pretix/presale/templates/pretixpresale/event/order_pay_confirm.html
#: pretix/presale/templates/pretixpresale/event/position_change.html
#: pretix/presale/templates/pretixpresale/event/position_modify.html
msgid "Cancel"
msgstr ""
#: pretix/control/templates/pretixcontrol/checkin/bulk_revert_confirm.html
#: pretix/control/templates/pretixcontrol/checkin/list_delete.html
#: pretix/control/templates/pretixcontrol/event/delete.html
@@ -19306,7 +19254,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/events/create_basics.html
msgid ""
"We strongly recommend against using short forms of more than 16 characters."
"We strongly recommend against using short forms of more then 16 characters."
msgstr ""
#: pretix/control/templates/pretixcontrol/events/create_basics.html
@@ -24246,7 +24194,6 @@ msgid "Add a new device"
msgstr ""
#: pretix/control/templates/pretixcontrol/user/2fa_main.html
#: pretix/control/templates/pretixcontrol/users/form.html
msgid "Emergency tokens"
msgstr ""
@@ -24491,26 +24438,6 @@ msgstr ""
msgid "Authentication backend"
msgstr ""
#: pretix/control/templates/pretixcontrol/users/form.html
msgid "Reset drift and throttle"
msgstr ""
#: pretix/control/templates/pretixcontrol/users/form.html
msgid "Available two-factor authentication methods"
msgstr ""
#: pretix/control/templates/pretixcontrol/users/form.html
#, python-format
msgid "1 failed attempt since %(date)s"
msgid_plural "%(cnt)s failed attempts since %(date)s"
msgstr[0] ""
msgstr[1] ""
#: pretix/control/templates/pretixcontrol/users/form.html
#, python-format
msgid "Currently locked until %(date)s"
msgstr ""
#: pretix/control/templates/pretixcontrol/users/form.html
msgid "Team memberships"
msgstr ""
@@ -24964,20 +24891,6 @@ msgstr ""
msgid "Invalid code, please try again."
msgstr ""
#: pretix/control/views/auth.py
#, python-brace-format
msgid "Invalid code. Please try again after waiting {value} minute."
msgid_plural "Invalid code. Please try again after waiting {value} minutes."
msgstr[0] ""
msgstr[1] ""
#: pretix/control/views/auth.py
#, python-brace-format
msgid "Invalid code. Please try again after waiting {value} second."
msgid_plural "Invalid code. Please try again after waiting {value} seconds."
msgstr[0] ""
msgstr[1] ""
#: pretix/control/views/checkin.py
msgid "The selected check-ins have been reverted."
msgstr ""
@@ -25730,10 +25643,6 @@ msgstr ""
msgid "You entered an order in an event with a different currency."
msgstr ""
#: pretix/control/views/orders.py
msgid "You entered an order in an event that you do not have access to."
msgstr ""
#: pretix/control/views/orders.py
msgid ""
"You can not refund more than the amount of a payment that is not yet "
@@ -25746,10 +25655,6 @@ msgid ""
"refunds."
msgstr ""
#: pretix/control/views/orders.py
msgid "The refunds you selected do not match the selected total refund amount."
msgstr ""
#: pretix/control/views/orders.py
#, python-brace-format
msgid ""
@@ -25791,6 +25696,10 @@ msgid ""
"Your {event} team"
msgstr ""
#: pretix/control/views/orders.py
msgid "The refunds you selected do not match the selected total refund amount."
msgstr ""
#: pretix/control/views/orders.py
msgid "The payment has been created successfully."
msgstr ""
@@ -26502,10 +26411,6 @@ msgid ""
"remain active."
msgstr ""
#: pretix/control/views/users.py
msgid "The drift values for TOTP devices have been reset."
msgstr ""
#: pretix/control/views/users.py
msgid "The new user has been created."
msgstr ""
@@ -26518,14 +26423,6 @@ msgstr ""
msgid "Bypass quota"
msgstr ""
#: pretix/control/views/vouchers.py
msgid "Budget"
msgstr ""
#: pretix/control/views/vouchers.py
msgid "Budget used"
msgstr ""
#: pretix/control/views/vouchers.py
msgid "The requested voucher does not exist."
msgstr ""
@@ -26678,11 +26575,12 @@ msgstr ""
#: pretix/plugins/autocheckin/apps.py pretix/plugins/badges/apps.py
#: pretix/plugins/banktransfer/apps.py pretix/plugins/checkinlists/apps.py
#: pretix/plugins/manualpayment/apps.py pretix/plugins/paypal2/apps.py
#: pretix/plugins/pretixdroid/apps.py pretix/plugins/reports/apps.py
#: pretix/plugins/returnurl/apps.py pretix/plugins/sendmail/apps.py
#: pretix/plugins/statistics/apps.py pretix/plugins/stripe/apps.py
#: pretix/plugins/ticketoutputpdf/apps.py pretix/plugins/webcheckin/apps.py
#: pretix/plugins/manualpayment/apps.py pretix/plugins/paypal/apps.py
#: pretix/plugins/paypal2/apps.py pretix/plugins/pretixdroid/apps.py
#: pretix/plugins/reports/apps.py pretix/plugins/returnurl/apps.py
#: pretix/plugins/sendmail/apps.py pretix/plugins/statistics/apps.py
#: pretix/plugins/stripe/apps.py pretix/plugins/ticketoutputpdf/apps.py
#: pretix/plugins/webcheckin/apps.py
msgid "the pretix team"
msgstr ""
@@ -27233,6 +27131,7 @@ msgstr ""
#: pretix/plugins/banktransfer/refund_export.py
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/control.html
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/import_assign.html
#: pretix/plugins/paypal/templates/pretixplugins/paypal/control.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control_legacy.html
msgid "Payer"
@@ -27726,7 +27625,8 @@ msgstr ""
msgid "Automatically checked in"
msgstr ""
#: pretix/plugins/checkinlists/exporters.py pretix/plugins/paypal2/payment.py
#: pretix/plugins/checkinlists/exporters.py pretix/plugins/paypal/payment.py
#: pretix/plugins/paypal2/payment.py
msgid "Secret"
msgstr ""
@@ -27785,6 +27685,152 @@ msgstr ""
msgid "A fully customizable payment method for manual processing."
msgstr ""
#: pretix/plugins/paypal/apps.py pretix/plugins/paypal/payment.py
#: pretix/plugins/paypal2/apps.py pretix/plugins/paypal2/payment.py
#: pretix/plugins/stripe/payment.py
msgid "PayPal"
msgstr ""
#: pretix/plugins/paypal/apps.py
msgid ""
"Accept payments with your PayPal account. PayPal is one of the most popular "
"payment methods world-wide."
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid ""
"The PayPal sandbox is being used, you can test without actually sending "
"money but you will need a PayPal sandbox user to log in."
msgstr ""
#: pretix/plugins/paypal/payment.py
msgid "PayPal account"
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid "Click here for a tutorial on how to obtain the required keys"
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
#: pretix/plugins/stripe/payment.py
msgid "Endpoint"
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid "Reference prefix"
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid ""
"Any value entered here will be added in front of the regular booking "
"reference containing the order number."
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid "Reference postfix"
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid ""
"Any value entered here will be added behind the regular booking reference "
"containing the order number."
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid "Disconnect from PayPal"
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid "We had trouble communicating with PayPal"
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid ""
"We were unable to process your payment. See below for details on how to "
"proceed."
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid ""
"PayPal has not yet approved the payment. We will inform you as soon as the "
"payment completed."
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
#, python-brace-format
msgid "Refunding the amount via PayPal failed: {}"
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid "The payment for this invoice has already been received."
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid "PayPal payment ID"
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid "PayPal sale ID"
msgstr ""
#: pretix/plugins/paypal/templates/pretixplugins/paypal/checkout_payment_confirm.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/checkout_payment_confirm.html
msgid ""
"The total amount listed above will be withdrawn from your PayPal account "
"after the confirmation of your purchase."
msgstr ""
#: pretix/plugins/paypal/templates/pretixplugins/paypal/checkout_payment_form.html
msgid ""
"After you clicked continue, we will redirect you to PayPal to fill in your "
"payment details. You will then be redirected back here to review and confirm "
"your order."
msgstr ""
#: pretix/plugins/paypal/templates/pretixplugins/paypal/control.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control_legacy.html
msgid "Sale ID"
msgstr ""
#: pretix/plugins/paypal/templates/pretixplugins/paypal/control.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control_legacy.html
msgid "Last update"
msgstr ""
#: pretix/plugins/paypal/templates/pretixplugins/paypal/control.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control_legacy.html
#: pretix/plugins/stripe/templates/pretixplugins/stripe/control.html
msgid "Total value"
msgstr ""
#: pretix/plugins/paypal/templates/pretixplugins/paypal/pending.html
msgid ""
"Our attempt to execute your Payment via PayPal has failed. Please try again "
"or contact us."
msgstr ""
#: pretix/plugins/paypal/templates/pretixplugins/paypal/pending.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/pending.html
msgid ""
"We're waiting for an answer from PayPal regarding your payment. Please "
"contact us, if this takes more than a few hours."
msgstr ""
#: pretix/plugins/paypal/views.py pretix/plugins/paypal2/views.py
msgid "Invalid response from PayPal received."
msgstr ""
#: pretix/plugins/paypal/views.py pretix/plugins/paypal2/views.py
msgid "It looks like you canceled the PayPal payment"
msgstr ""
#: pretix/plugins/paypal/views.py pretix/plugins/paypal2/views.py
msgid "Your PayPal account has been disconnected."
msgstr ""
#: pretix/plugins/paypal2/apps.py
msgid ""
"Accept payments with your PayPal account. In addition to regular PayPal "
@@ -27794,23 +27840,10 @@ msgid ""
"methods world-wide."
msgstr ""
#: pretix/plugins/paypal2/apps.py pretix/plugins/paypal2/payment.py
#: pretix/plugins/stripe/payment.py
msgid "PayPal"
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid "PayPal Merchant ID"
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid "Click here for a tutorial on how to obtain the required keys"
msgstr ""
#: pretix/plugins/paypal2/payment.py pretix/plugins/stripe/payment.py
msgid "Endpoint"
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid ""
"Even if a customer chooses an Alternative Payment Method, they will always "
@@ -27879,26 +27912,6 @@ msgid ""
"while the last payment is still under investigation."
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid "Reference prefix"
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid ""
"Any value entered here will be added in front of the regular booking "
"reference containing the order number."
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid "Reference postfix"
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid ""
"Any value entered here will be added behind the regular booking reference "
"containing the order number."
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid "-- Automatic --"
msgstr ""
@@ -27919,10 +27932,6 @@ msgstr ""
msgid "Connect with {icon} PayPal"
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid "Disconnect from PayPal"
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid ""
"Please configure a PayPal Webhook to the following endpoint in order to "
@@ -27951,12 +27960,6 @@ msgstr ""
msgid "An error occurred during connecting with PayPal, please try again."
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid ""
"The PayPal sandbox is being used, you can test without actually sending "
"money but you will need a PayPal sandbox user to log in."
msgstr ""
#: pretix/plugins/paypal2/payment.py
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/pending.html
msgid ""
@@ -27965,10 +27968,6 @@ msgid ""
"attempt. You can also try other payment methods, if available."
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid "We had trouble communicating with PayPal"
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid ""
"Something went wrong when requesting the payment status. Please try again."
@@ -27978,41 +27977,12 @@ msgstr ""
msgid "You may need to enable JavaScript for PayPal payments."
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid ""
"We were unable to process your payment. See below for details on how to "
"proceed."
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid ""
"PayPal has not yet approved the payment. We will inform you as soon as the "
"payment completed."
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid ""
"Refunding the amount via PayPal failed: The original payment does not "
"contain the required information to issue an automated refund."
msgstr ""
#: pretix/plugins/paypal2/payment.py
#, python-brace-format
msgid "Refunding the amount via PayPal failed: {}"
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid "The payment for this invoice has already been received."
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid "PayPal payment ID"
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid "PayPal sale ID"
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid "PayPal APM"
msgstr ""
@@ -28100,12 +28070,6 @@ msgstr ""
msgid "We will then charge your PayPal account and finalize the order."
msgstr ""
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/checkout_payment_confirm.html
msgid ""
"The total amount listed above will be withdrawn from your PayPal account "
"after the confirmation of your purchase."
msgstr ""
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/checkout_payment_confirm.html
msgid ""
"After placing your order, you will be able to select your desired payment "
@@ -28137,11 +28101,6 @@ msgid ""
"different payment method, if you prefer."
msgstr ""
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control_legacy.html
msgid "Sale ID"
msgstr ""
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control.html
msgid "Capture status"
msgstr ""
@@ -28152,17 +28111,6 @@ msgid ""
"money will not be disbursed and the order remain in its pending state."
msgstr ""
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control_legacy.html
msgid "Last update"
msgstr ""
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control_legacy.html
#: pretix/plugins/stripe/templates/pretixplugins/stripe/control.html
msgid "Total value"
msgstr ""
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/pay.html
#: pretix/plugins/stripe/templates/pretixplugins/stripe/sca.html
#: pretix/plugins/stripe/templates/pretixplugins/stripe/sca_return.html
@@ -28196,12 +28144,6 @@ msgid ""
"to resolve this case."
msgstr ""
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/pending.html
msgid ""
"We're waiting for an answer from PayPal regarding your payment. Please "
"contact us, if this takes more than a few hours."
msgstr ""
#: pretix/plugins/paypal2/views.py
msgid ""
"An error occurred returning from PayPal: request parameters missing. Please "
@@ -28232,18 +28174,6 @@ msgid ""
"in detail below."
msgstr ""
#: pretix/plugins/paypal2/views.py
msgid "Invalid response from PayPal received."
msgstr ""
#: pretix/plugins/paypal2/views.py
msgid "It looks like you canceled the PayPal payment"
msgstr ""
#: pretix/plugins/paypal2/views.py
msgid "Your PayPal account has been disconnected."
msgstr ""
#: pretix/plugins/pretixdroid/apps.py
msgid "Old check-in device API"
msgstr ""
@@ -30263,6 +30193,7 @@ msgstr ""
#: pretix/presale/forms/order.py
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
msgid "plus taxes"
msgstr ""
@@ -30683,31 +30614,6 @@ msgid ""
"Please go to the payment settings and activate one or more payment providers."
msgstr ""
#: pretix/presale/templates/pretixpresale/event/checkout_payment.html
msgid ""
"Not sure yet? You can complete your order first and then select a payment "
"method later."
msgstr ""
#: pretix/presale/templates/pretixpresale/event/checkout_payment.html
msgid ""
"To do so, please first remove the payment methods you already selected above."
msgstr ""
#: pretix/presale/templates/pretixpresale/event/checkout_payment.html
#, python-format
msgid "Your payment needs to be completed within %(minutes)s minutes."
msgstr ""
#: pretix/presale/templates/pretixpresale/event/checkout_payment.html
#, python-format
msgid "Your payment needs to be completed by %(deadline)s."
msgstr ""
#: pretix/presale/templates/pretixpresale/event/checkout_payment.html
msgid "Proceed without selection"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/checkout_questions.html
msgid "Before we continue, we need you to answer some questions."
msgstr ""
@@ -30774,12 +30680,14 @@ msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
#, python-format
msgid "minimum amount to order: %(num)s"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
msgctxt "price"
msgid "free"
msgstr ""
@@ -30808,56 +30716,66 @@ msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
msgid "Original price:"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
msgid "New price:"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
#, python-format
msgid "Modify price for %(item)s, at least %(price)s"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
#, python-format
msgid "Modify price for %(item)s"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
msgid "incl. taxes"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
#, python-format
msgid "<strong>plus</strong> %(rate)s%% %(name)s"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
#, python-format
msgid "incl. %(rate)s%% %(name)s"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
msgctxt "checkbox"
msgid "Select"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
msgid "Decrease quantity"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
msgid "Increase quantity"
msgstr ""
@@ -31318,10 +31236,12 @@ msgid "Your order qualifies for a discount"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
msgid "Uncategorized items"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
#, python-format
msgid "Show full-size image of %(item)s"
msgstr ""
@@ -31334,16 +31254,19 @@ msgstr[0] ""
msgstr[1] ""
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
#, python-format
msgid "%(value)s incl. taxes"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
#, python-format
msgid "%(value)s without taxes"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
#, python-format
msgid "Set price in %(currency)s for %(item)s"
msgstr ""
@@ -32002,6 +31925,11 @@ msgid ""
"products at the specified price:"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/voucher.html
#, python-format
msgid "from %(minprice)s"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/voucher.html
#, python-format
msgid "You need to select at least %(number)s products."
+84 -1
View File
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-30 07:26+0000\n"
"POT-Creation-Date: 2026-07-06 15:52+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"
@@ -766,163 +766,194 @@ msgstr ""
msgid "Google Pay"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Quantity"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Decrease quantity"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Increase quantity"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Filter events by"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Filter"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Price"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "Original price: %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "New price: %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Select"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "Select %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "Select variant %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Sold out"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Buy"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Register"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Reserved"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "FREE"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "from %(currency)s %(price)s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "Image of %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "incl. %(rate)s% %(taxname)s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "plus %(rate)s% %(taxname)s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "incl. taxes"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "plus taxes"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "currently available: %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Only available with a voucher"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Not yet available"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Not available anymore"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Currently not available"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "minimum amount to order: %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Close ticket shop"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "The ticket shop could not be loaded."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid ""
@@ -930,21 +961,25 @@ msgid ""
"in a new tab to continue."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Open ticket shop"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Checkout"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "The cart could not be created. Please try again later"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid ""
@@ -952,11 +987,13 @@ msgid ""
"this ticket shop. Please click \"Continue\" to retry in a new tab."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Waiting list"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid ""
@@ -964,96 +1001,115 @@ msgid ""
"products, they will be added to your existing cart."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Resume checkout"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Redeem a voucher"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Redeem"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Voucher code"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Close"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Close checkout"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "You cannot cancel this operation. Please wait for loading to finish."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Continue"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Show variants"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Hide variants"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Choose a different event"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Choose a different date"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Back"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Next month"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Previous month"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Next week"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Previous week"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Open seat selection"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid ""
@@ -1062,111 +1118,138 @@ msgid ""
"again."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Load more"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Mo"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Tu"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "We"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Th"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Fr"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Sa"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Su"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Monday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Tuesday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Wednesday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Thursday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Friday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Saturday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Sunday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "January"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "February"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "March"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "April"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "May"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "June"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "July"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "August"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "September"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "October"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "November"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "December"
msgstr ""
File diff suppressed because it is too large Load Diff
+89 -7
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-30 07:26+0000\n"
"POT-Creation-Date: 2026-07-06 15:52+0000\n"
"PO-Revision-Date: 2026-07-13 11:28+0000\n"
"Last-Translator: ahmed badr <ahmedbadr@oma.com.eg>\n"
"Language-Team: Arabic <https://translate.pretix.eu/projects/pretix/pretix-js/"
@@ -648,8 +648,7 @@ msgstr "خطأ غير معروف."
#: pretix/static/pretixcontrol/js/ui/main.js
msgid "Your color has great contrast and will provide excellent accessibility."
msgstr ""
"يتميز لونك بتباين رائع ويسهل قراءته للغاية! وسيوفر إمكانية وصول ممتازة."
msgstr "يتميز لونك بتباين رائع ويسهل قراءته للغاية! وسيوفر إمكانية وصول ممتازة."
#: pretix/static/pretixcontrol/js/ui/main.js
msgid ""
@@ -664,8 +663,8 @@ msgid ""
"Your color has insufficient contrast to white. Accessibility of your site "
"will be impacted."
msgstr ""
"اللون الذي اخترته لا يتمتع بتباين كافٍ مع اللون الأبيض. وسيؤثر ذلك على "
"إمكانية الوصول إلى موقعك."
"اللون الذي اخترته لا يتمتع بتباين كافٍ مع اللون الأبيض. وسيؤثر ذلك على إمكانية "
"الوصول إلى موقعك."
#: pretix/static/pretixcontrol/js/ui/main.js
msgid "Search query"
@@ -795,163 +794,194 @@ msgstr "التوقيت المحلي:"
msgid "Google Pay"
msgstr "Google Pay"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Quantity"
msgstr "الكمية"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Decrease quantity"
msgstr "تقليل الكمية"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Increase quantity"
msgstr "زيادة الكمية"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Filter events by"
msgstr "تصفية الأحداث حسب"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Filter"
msgstr "فلتر"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Price"
msgstr "السعر"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "Original price: %s"
msgstr "السعر الأصلي: %s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "New price: %s"
msgstr "السعر الجديد: %s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Select"
msgstr "المختارة فقط"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "Select %s"
msgstr "تم اختيار %s فقط"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "Select variant %s"
msgstr "اختر النوع %s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Sold out"
msgstr "تم البيع بالكامل"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Buy"
msgstr "اشتري"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Register"
msgstr "سجل"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Reserved"
msgstr "محجوز"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "FREE"
msgstr "مجاني"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "from %(currency)s %(price)s"
msgstr "من %(currency) s %(price)s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "Image of %s"
msgstr "صورة لـ %s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "incl. %(rate)s% %(taxname)s"
msgstr "يشمل %(rate)s% %(taxname)s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "plus %(rate)s% %(taxname)s"
msgstr "بالإضافة إلى %(rate)s% %(taxname)s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "incl. taxes"
msgstr "شامل الضريبة"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "plus taxes"
msgstr "بالإضافة إلى الضرائب"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "currently available: %s"
msgstr "متوفر حاليا: %s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Only available with a voucher"
msgstr "متوفرة مع القسيمة فقط"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Not yet available"
msgstr "حاليًا غير متوفر: %s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Not available anymore"
msgstr "لم يعد متوفراً"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Currently not available"
msgstr "غير متوفر حاليًا: %s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "minimum amount to order: %s"
msgstr "الحد الأدنى للطلب: %s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Close ticket shop"
msgstr "إغلاق متجر التذاكر"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "The ticket shop could not be loaded."
msgstr "لا يمكن تحميل متجر التذاكر."
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid ""
@@ -961,21 +991,25 @@ msgstr ""
"يوجد حالياً عدد كبير من المستخدمين في متجر التذاكر هذا. يرجى فتح المتجر في "
"علامة تبويب جديدة للمتابعة."
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Open ticket shop"
msgstr "إغلاق/فتح متجر التذاكر"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Checkout"
msgstr "استئناف عملية الدفع"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "The cart could not be created. Please try again later"
msgstr "لا يمكن إنشاء سلة التسوق. الرجاء المحاولة مرة أخرى في وقت لاحق"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid ""
@@ -983,14 +1017,16 @@ msgid ""
"this ticket shop. Please click \"Continue\" to retry in a new tab."
msgstr ""
"لم نتمكن من إنشاء سلة التسوق الخاصة بك، نظرًا لوجود عدد كبير جدًّا من "
"المستخدمين حاليًّا في متجر التذاكر هذا. يرجى النقر على «متابعة» لإعادة "
"المحاولة في علامة تبويب جديدة."
"المستخدمين حاليًّا في متجر التذاكر هذا. يرجى النقر على «متابعة» لإعادة المحاولة "
"في علامة تبويب جديدة."
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Waiting list"
msgstr "قائمة الإنتظار"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid ""
@@ -1000,96 +1036,115 @@ msgstr ""
"لديك الآن سلة تسوق مفعلة لهذا الحدث. إذا قمت باختيار منتجات أخرى سيتم "
"إضافتها إلى سلة التسوق الموجودة حالياً."
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Resume checkout"
msgstr "استئناف الدفع"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Redeem a voucher"
msgstr "استبدال قسيمة"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Redeem"
msgstr "استبدال"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Voucher code"
msgstr "رمز القسيمة"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Close"
msgstr "إغلاق"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Close checkout"
msgstr "إغلاق عملية الدفع"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "You cannot cancel this operation. Please wait for loading to finish."
msgstr "لا يمكنك إلغاء هذه العملية. يرجى الانتظار حتى ينتهي التحميل."
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Continue"
msgstr "استمرار"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Show variants"
msgstr "انظر الاختلافات"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Hide variants"
msgstr "إخفاء الاختلافات"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Choose a different event"
msgstr "اختر فعالية أخرى"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Choose a different date"
msgstr "اختر تاريخا آخر"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Back"
msgstr "العودة"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Next month"
msgstr "الشهر القادم"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Previous month"
msgstr "الشهر السابق"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Next week"
msgstr "الأسبوع القادم"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Previous week"
msgstr "الأسبوع السابق"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Open seat selection"
msgstr "خيارات المقاعد"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid ""
@@ -1100,111 +1155,138 @@ msgstr ""
"تم بيع جميع فئات التذاكر أو بعضها حاليًا. إذا أردت، يمكنك إضافة اسمك إلى "
"قائمة الانتظار. وسنقوم بإخطارك إذا توفرت مقاعد مرة أخرى."
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Load more"
msgstr "تحميل المزيد"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Mo"
msgstr "الإثنين"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Tu"
msgstr "الثلاثاء"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "We"
msgstr "الأربعاء"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Th"
msgstr "الخميس"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Fr"
msgstr "الجمعة"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Sa"
msgstr "السبت"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Su"
msgstr "الأحد"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Monday"
msgstr "الاثنين"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Tuesday"
msgstr "الثلاثاء"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Wednesday"
msgstr "الأربعاء"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Thursday"
msgstr "الخميس"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Friday"
msgstr "الجمعة"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Saturday"
msgstr "السبت"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Sunday"
msgstr "الأحد"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "January"
msgstr "يناير"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "February"
msgstr "فبراير"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "March"
msgstr "مارس"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "April"
msgstr "أبريل"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "May"
msgstr "هناك"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "June"
msgstr "يونيو"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "July"
msgstr "يوليو"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "August"
msgstr "أغسطس"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "September"
msgstr "سبتمبر"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "October"
msgstr "أكتوبر"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "November"
msgstr "نوفمبر"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "December"
msgstr "ديسمبر"
+274 -346
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-30 07:26+0000\n"
"POT-Creation-Date: 2026-08-24 15:35+0000\n"
"PO-Revision-Date: 2024-12-11 01:00+0000\n"
"Last-Translator: Neriman Memmedli <nerim4n@pm.me>\n"
"Language-Team: Azerbaijani <https://translate.pretix.eu/projects/pretix/"
@@ -198,7 +198,7 @@ msgid "Allowed Post Logout URIs list, space separated"
msgstr ""
#: pretix/api/models.py pretix/base/models/customers.py
#: pretix/plugins/paypal2/payment.py
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid "Client ID"
msgstr ""
@@ -1718,18 +1718,6 @@ msgstr ""
msgid "Payment providers"
msgstr ""
#: pretix/base/exporters/invoices.py pretix/base/models/orders.py
msgid "Transmission type"
msgstr ""
#: pretix/base/exporters/invoices.py
msgid "Transmission status"
msgstr ""
#: pretix/base/exporters/invoices.py
msgid "Transmission date"
msgstr ""
#: pretix/base/exporters/invoices.py
msgid "Cancellation"
msgstr ""
@@ -2373,6 +2361,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/organizers/giftcard.html
#: pretix/plugins/banktransfer/refund_export.py
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/import_form.html
#: pretix/plugins/paypal/templates/pretixplugins/paypal/control.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control_legacy.html
#: pretix/plugins/stripe/templates/pretixplugins/stripe/control.html
@@ -2396,6 +2385,7 @@ msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
msgid "Quantity"
msgstr ""
@@ -2477,6 +2467,7 @@ msgstr ""
#: pretix/base/exporters/orderlist.py
#: pretix/control/templates/pretixcontrol/search/payments.html
#: pretix/plugins/paypal/templates/pretixplugins/paypal/control.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control_legacy.html
msgid "Payment ID"
msgstr ""
@@ -4234,10 +4225,6 @@ msgstr ""
msgid "Initialization date"
msgstr ""
#: pretix/base/models/devices.py
msgid "Security profile"
msgstr ""
#: pretix/base/models/discount.py
msgctxt "subevent"
msgid "Dates can be mixed without limitation"
@@ -5453,10 +5440,6 @@ msgstr ""
msgid "Maximum value"
msgstr ""
#: pretix/base/models/items.py
msgid "Minimum length"
msgstr ""
#: pretix/base/models/items.py
msgid "Maximum length"
msgstr ""
@@ -5523,10 +5506,6 @@ msgstr ""
msgid "The maximum value must not be lower than the minimum value."
msgstr ""
#: pretix/base/models/items.py
msgid "The maximum length must not be shorter than the minimum length."
msgstr ""
#: pretix/base/models/items.py
msgid ""
"The system already contains answers to this question that are not compatible "
@@ -6020,6 +5999,10 @@ msgstr ""
msgid "This reference will be printed on your invoice for your convenience."
msgstr ""
#: pretix/base/models/orders.py
msgid "Transmission type"
msgstr ""
#: pretix/base/models/orders.py
#: pretix/plugins/badges/templates/pretixplugins/badges/control_order_position_buttons.html
msgid "Badge"
@@ -9493,17 +9476,6 @@ msgid ""
"'Last date of payments' configured above."
msgstr ""
#: pretix/base/settings.py
msgid "Allow postponed payment choice for sales channels"
msgstr ""
#: pretix/base/settings.py
msgid ""
"If postponed payment is allowed on a sales channel, customers can complete "
"their order without selecting a payment method. This is useful whenever "
"orders are not created by the same person who is making the payment."
msgstr ""
#: pretix/base/settings.py
msgid "Show start date"
msgstr ""
@@ -10025,6 +9997,12 @@ msgstr ""
msgid "Hide all unavailable dates from calendar or list views"
msgstr ""
#: pretix/base/settings.py
msgid ""
"This option currently only affects the calendar of this event series, not "
"the organizer-wide calendar."
msgstr ""
#: pretix/base/settings.py
msgid "Hide all past dates from calendar"
msgstr ""
@@ -14713,11 +14691,6 @@ msgctxt "rrule"
msgid "third"
msgstr ""
#: pretix/control/forms/rrule.py
msgctxt "rrule"
msgid "fourth"
msgstr ""
#: pretix/control/forms/rrule.py
msgctxt "rrule"
msgid "last"
@@ -15701,22 +15674,6 @@ msgstr ""
msgid "Queued emails have been aborted."
msgstr ""
#: pretix/control/logdisplay.py
msgid "An organizer meta property has been created."
msgstr ""
#: pretix/control/logdisplay.py
msgid "An organizer meta property has been deleted."
msgstr ""
#: pretix/control/logdisplay.py
msgid "An organizer meta property has been changed."
msgstr ""
#: pretix/control/logdisplay.py
msgid "An organizer meta property has been reordered."
msgstr ""
#: pretix/control/logdisplay.py
msgid "Gift card acceptance for another organizer has been added."
msgstr ""
@@ -15919,10 +15876,6 @@ msgstr ""
msgid "A two-factor emergency code has been generated."
msgstr ""
#: pretix/control/logdisplay.py
msgid "Drift and throttle values for two-factor devices have been reset."
msgstr ""
#: pretix/control/logdisplay.py
#, python-brace-format
msgid ""
@@ -16755,87 +16708,6 @@ msgid ""
"Granting access to your pretix account happens at your own risk."
msgstr ""
#: pretix/control/templates/pretixcontrol/auth/oauth_authorization.html
#: pretix/control/templates/pretixcontrol/checkin/bulk_revert_confirm.html
#: pretix/control/templates/pretixcontrol/checkin/list_delete.html
#: pretix/control/templates/pretixcontrol/checkin/reset.html
#: pretix/control/templates/pretixcontrol/datasync/control_order_info.html
#: pretix/control/templates/pretixcontrol/email_setup_simple.html
#: pretix/control/templates/pretixcontrol/event/tax_delete.html
#: pretix/control/templates/pretixcontrol/item/delete.html
#: pretix/control/templates/pretixcontrol/items/category_delete.html
#: pretix/control/templates/pretixcontrol/items/discount_delete.html
#: pretix/control/templates/pretixcontrol/items/question_delete.html
#: pretix/control/templates/pretixcontrol/items/quota_delete.html
#: pretix/control/templates/pretixcontrol/items/quota_delete_bulk.html
#: pretix/control/templates/pretixcontrol/oauth/app_delete.html
#: pretix/control/templates/pretixcontrol/oauth/app_rollkeys.html
#: pretix/control/templates/pretixcontrol/oauth/auth_revoke.html
#: pretix/control/templates/pretixcontrol/order/change.html
#: pretix/control/templates/pretixcontrol/order/change_contact.html
#: pretix/control/templates/pretixcontrol/order/change_locale.html
#: pretix/control/templates/pretixcontrol/order/change_questions.html
#: pretix/control/templates/pretixcontrol/order/extend.html
#: pretix/control/templates/pretixcontrol/order/pay.html
#: pretix/control/templates/pretixcontrol/order/pay_complete.html
#: pretix/control/templates/pretixcontrol/order/reactivate.html
#: pretix/control/templates/pretixcontrol/order/refund_choose.html
#: pretix/control/templates/pretixcontrol/order/refund_done.html
#: pretix/control/templates/pretixcontrol/order/refund_process.html
#: pretix/control/templates/pretixcontrol/order/refund_start.html
#: pretix/control/templates/pretixcontrol/orders/bulk_action.html
#: pretix/control/templates/pretixcontrol/orders/export_delete.html
#: pretix/control/templates/pretixcontrol/orders/refunds.html
#: pretix/control/templates/pretixcontrol/organizers/channel_delete.html
#: pretix/control/templates/pretixcontrol/organizers/customer_anonymize.html
#: pretix/control/templates/pretixcontrol/organizers/customer_membership_delete.html
#: pretix/control/templates/pretixcontrol/organizers/device_revoke.html
#: pretix/control/templates/pretixcontrol/organizers/export_delete.html
#: pretix/control/templates/pretixcontrol/organizers/gate_delete.html
#: pretix/control/templates/pretixcontrol/organizers/membershiptype_delete.html
#: pretix/control/templates/pretixcontrol/organizers/property_delete.html
#: pretix/control/templates/pretixcontrol/organizers/ssoclient_delete.html
#: pretix/control/templates/pretixcontrol/organizers/ssoprovider_delete.html
#: pretix/control/templates/pretixcontrol/organizers/team_delete.html
#: pretix/control/templates/pretixcontrol/pdf/index.html
#: pretix/control/templates/pretixcontrol/subevents/bulk_edit.html
#: pretix/control/templates/pretixcontrol/subevents/delete.html
#: pretix/control/templates/pretixcontrol/subevents/delete_bulk.html
#: pretix/control/templates/pretixcontrol/subevents/edit.html
#: pretix/control/templates/pretixcontrol/user/2fa_delete.html
#: pretix/control/templates/pretixcontrol/user/2fa_disable.html
#: pretix/control/templates/pretixcontrol/user/2fa_enable.html
#: pretix/control/templates/pretixcontrol/user/2fa_leaveteams.html
#: pretix/control/templates/pretixcontrol/user/2fa_regenemergency.html
#: pretix/control/templates/pretixcontrol/user/change_email.html
#: pretix/control/templates/pretixcontrol/user/change_password.html
#: pretix/control/templates/pretixcontrol/user/confirmation_code_dialog.html
#: pretix/control/templates/pretixcontrol/vouchers/delete.html
#: pretix/control/templates/pretixcontrol/vouchers/delete_bulk.html
#: pretix/control/templates/pretixcontrol/vouchers/delete_carts.html
#: pretix/control/templates/pretixcontrol/waitinglist/delete.html
#: pretix/control/templates/pretixcontrol/waitinglist/delete_bulk.html
#: pretix/control/templates/pretixcontrol/waitinglist/edit.html
#: pretix/plugins/autocheckin/templates/pretixplugins/autocheckin/delete.html
#: pretix/plugins/badges/templates/pretixplugins/badges/delete.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/pay.html
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_delete.html
#: pretix/plugins/stripe/templates/pretixplugins/stripe/sca.html
#: pretix/plugins/ticketoutputpdf/templates/pretixplugins/ticketoutputpdf/delete.html
#: pretix/presale/templates/pretixpresale/event/order_change.html
#: pretix/presale/templates/pretixpresale/event/order_modify.html
#: pretix/presale/templates/pretixpresale/event/order_pay.html
#: pretix/presale/templates/pretixpresale/event/order_pay_change.html
#: pretix/presale/templates/pretixpresale/event/order_pay_confirm.html
#: pretix/presale/templates/pretixpresale/event/position_change.html
#: pretix/presale/templates/pretixpresale/event/position_modify.html
msgid "Cancel"
msgstr ""
#: pretix/control/templates/pretixcontrol/auth/oauth_authorization.html
msgid "Authorize"
msgstr ""
#: pretix/control/templates/pretixcontrol/auth/oauth_authorization.html
msgid "Error:"
msgstr ""
@@ -17197,6 +17069,82 @@ msgid_plural ""
msgstr[0] ""
msgstr[1] ""
#: pretix/control/templates/pretixcontrol/checkin/bulk_revert_confirm.html
#: pretix/control/templates/pretixcontrol/checkin/list_delete.html
#: pretix/control/templates/pretixcontrol/checkin/reset.html
#: pretix/control/templates/pretixcontrol/datasync/control_order_info.html
#: pretix/control/templates/pretixcontrol/email_setup_simple.html
#: pretix/control/templates/pretixcontrol/event/tax_delete.html
#: pretix/control/templates/pretixcontrol/item/delete.html
#: pretix/control/templates/pretixcontrol/items/category_delete.html
#: pretix/control/templates/pretixcontrol/items/discount_delete.html
#: pretix/control/templates/pretixcontrol/items/question_delete.html
#: pretix/control/templates/pretixcontrol/items/quota_delete.html
#: pretix/control/templates/pretixcontrol/items/quota_delete_bulk.html
#: pretix/control/templates/pretixcontrol/oauth/app_delete.html
#: pretix/control/templates/pretixcontrol/oauth/app_rollkeys.html
#: pretix/control/templates/pretixcontrol/oauth/auth_revoke.html
#: pretix/control/templates/pretixcontrol/order/change.html
#: pretix/control/templates/pretixcontrol/order/change_contact.html
#: pretix/control/templates/pretixcontrol/order/change_locale.html
#: pretix/control/templates/pretixcontrol/order/change_questions.html
#: pretix/control/templates/pretixcontrol/order/extend.html
#: pretix/control/templates/pretixcontrol/order/pay.html
#: pretix/control/templates/pretixcontrol/order/pay_complete.html
#: pretix/control/templates/pretixcontrol/order/reactivate.html
#: pretix/control/templates/pretixcontrol/order/refund_choose.html
#: pretix/control/templates/pretixcontrol/order/refund_done.html
#: pretix/control/templates/pretixcontrol/order/refund_process.html
#: pretix/control/templates/pretixcontrol/order/refund_start.html
#: pretix/control/templates/pretixcontrol/orders/bulk_action.html
#: pretix/control/templates/pretixcontrol/orders/export_delete.html
#: pretix/control/templates/pretixcontrol/orders/refunds.html
#: pretix/control/templates/pretixcontrol/organizers/channel_delete.html
#: pretix/control/templates/pretixcontrol/organizers/customer_anonymize.html
#: pretix/control/templates/pretixcontrol/organizers/customer_membership_delete.html
#: pretix/control/templates/pretixcontrol/organizers/device_revoke.html
#: pretix/control/templates/pretixcontrol/organizers/export_delete.html
#: pretix/control/templates/pretixcontrol/organizers/gate_delete.html
#: pretix/control/templates/pretixcontrol/organizers/membershiptype_delete.html
#: pretix/control/templates/pretixcontrol/organizers/property_delete.html
#: pretix/control/templates/pretixcontrol/organizers/ssoclient_delete.html
#: pretix/control/templates/pretixcontrol/organizers/ssoprovider_delete.html
#: pretix/control/templates/pretixcontrol/organizers/team_delete.html
#: pretix/control/templates/pretixcontrol/pdf/index.html
#: pretix/control/templates/pretixcontrol/subevents/bulk_edit.html
#: pretix/control/templates/pretixcontrol/subevents/delete.html
#: pretix/control/templates/pretixcontrol/subevents/delete_bulk.html
#: pretix/control/templates/pretixcontrol/subevents/edit.html
#: pretix/control/templates/pretixcontrol/user/2fa_delete.html
#: pretix/control/templates/pretixcontrol/user/2fa_disable.html
#: pretix/control/templates/pretixcontrol/user/2fa_enable.html
#: pretix/control/templates/pretixcontrol/user/2fa_leaveteams.html
#: pretix/control/templates/pretixcontrol/user/2fa_regenemergency.html
#: pretix/control/templates/pretixcontrol/user/change_email.html
#: pretix/control/templates/pretixcontrol/user/change_password.html
#: pretix/control/templates/pretixcontrol/user/confirmation_code_dialog.html
#: pretix/control/templates/pretixcontrol/vouchers/delete.html
#: pretix/control/templates/pretixcontrol/vouchers/delete_bulk.html
#: pretix/control/templates/pretixcontrol/vouchers/delete_carts.html
#: pretix/control/templates/pretixcontrol/waitinglist/delete.html
#: pretix/control/templates/pretixcontrol/waitinglist/delete_bulk.html
#: pretix/control/templates/pretixcontrol/waitinglist/edit.html
#: pretix/plugins/autocheckin/templates/pretixplugins/autocheckin/delete.html
#: pretix/plugins/badges/templates/pretixplugins/badges/delete.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/pay.html
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_delete.html
#: pretix/plugins/stripe/templates/pretixplugins/stripe/sca.html
#: pretix/plugins/ticketoutputpdf/templates/pretixplugins/ticketoutputpdf/delete.html
#: pretix/presale/templates/pretixpresale/event/order_change.html
#: pretix/presale/templates/pretixpresale/event/order_modify.html
#: pretix/presale/templates/pretixpresale/event/order_pay.html
#: pretix/presale/templates/pretixpresale/event/order_pay_change.html
#: pretix/presale/templates/pretixpresale/event/order_pay_confirm.html
#: pretix/presale/templates/pretixpresale/event/position_change.html
#: pretix/presale/templates/pretixpresale/event/position_modify.html
msgid "Cancel"
msgstr ""
#: pretix/control/templates/pretixcontrol/checkin/bulk_revert_confirm.html
#: pretix/control/templates/pretixcontrol/checkin/list_delete.html
#: pretix/control/templates/pretixcontrol/event/delete.html
@@ -19308,7 +19256,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/events/create_basics.html
msgid ""
"We strongly recommend against using short forms of more than 16 characters."
"We strongly recommend against using short forms of more then 16 characters."
msgstr ""
#: pretix/control/templates/pretixcontrol/events/create_basics.html
@@ -24248,7 +24196,6 @@ msgid "Add a new device"
msgstr ""
#: pretix/control/templates/pretixcontrol/user/2fa_main.html
#: pretix/control/templates/pretixcontrol/users/form.html
msgid "Emergency tokens"
msgstr ""
@@ -24493,26 +24440,6 @@ msgstr ""
msgid "Authentication backend"
msgstr ""
#: pretix/control/templates/pretixcontrol/users/form.html
msgid "Reset drift and throttle"
msgstr ""
#: pretix/control/templates/pretixcontrol/users/form.html
msgid "Available two-factor authentication methods"
msgstr ""
#: pretix/control/templates/pretixcontrol/users/form.html
#, python-format
msgid "1 failed attempt since %(date)s"
msgid_plural "%(cnt)s failed attempts since %(date)s"
msgstr[0] ""
msgstr[1] ""
#: pretix/control/templates/pretixcontrol/users/form.html
#, python-format
msgid "Currently locked until %(date)s"
msgstr ""
#: pretix/control/templates/pretixcontrol/users/form.html
msgid "Team memberships"
msgstr ""
@@ -24966,20 +24893,6 @@ msgstr ""
msgid "Invalid code, please try again."
msgstr ""
#: pretix/control/views/auth.py
#, python-brace-format
msgid "Invalid code. Please try again after waiting {value} minute."
msgid_plural "Invalid code. Please try again after waiting {value} minutes."
msgstr[0] ""
msgstr[1] ""
#: pretix/control/views/auth.py
#, python-brace-format
msgid "Invalid code. Please try again after waiting {value} second."
msgid_plural "Invalid code. Please try again after waiting {value} seconds."
msgstr[0] ""
msgstr[1] ""
#: pretix/control/views/checkin.py
msgid "The selected check-ins have been reverted."
msgstr ""
@@ -25732,10 +25645,6 @@ msgstr ""
msgid "You entered an order in an event with a different currency."
msgstr ""
#: pretix/control/views/orders.py
msgid "You entered an order in an event that you do not have access to."
msgstr ""
#: pretix/control/views/orders.py
msgid ""
"You can not refund more than the amount of a payment that is not yet "
@@ -25748,10 +25657,6 @@ msgid ""
"refunds."
msgstr ""
#: pretix/control/views/orders.py
msgid "The refunds you selected do not match the selected total refund amount."
msgstr ""
#: pretix/control/views/orders.py
#, python-brace-format
msgid ""
@@ -25793,6 +25698,10 @@ msgid ""
"Your {event} team"
msgstr ""
#: pretix/control/views/orders.py
msgid "The refunds you selected do not match the selected total refund amount."
msgstr ""
#: pretix/control/views/orders.py
msgid "The payment has been created successfully."
msgstr ""
@@ -26504,10 +26413,6 @@ msgid ""
"remain active."
msgstr ""
#: pretix/control/views/users.py
msgid "The drift values for TOTP devices have been reset."
msgstr ""
#: pretix/control/views/users.py
msgid "The new user has been created."
msgstr ""
@@ -26520,14 +26425,6 @@ msgstr ""
msgid "Bypass quota"
msgstr ""
#: pretix/control/views/vouchers.py
msgid "Budget"
msgstr ""
#: pretix/control/views/vouchers.py
msgid "Budget used"
msgstr ""
#: pretix/control/views/vouchers.py
msgid "The requested voucher does not exist."
msgstr ""
@@ -26682,11 +26579,12 @@ msgstr ""
#: pretix/plugins/autocheckin/apps.py pretix/plugins/badges/apps.py
#: pretix/plugins/banktransfer/apps.py pretix/plugins/checkinlists/apps.py
#: pretix/plugins/manualpayment/apps.py pretix/plugins/paypal2/apps.py
#: pretix/plugins/pretixdroid/apps.py pretix/plugins/reports/apps.py
#: pretix/plugins/returnurl/apps.py pretix/plugins/sendmail/apps.py
#: pretix/plugins/statistics/apps.py pretix/plugins/stripe/apps.py
#: pretix/plugins/ticketoutputpdf/apps.py pretix/plugins/webcheckin/apps.py
#: pretix/plugins/manualpayment/apps.py pretix/plugins/paypal/apps.py
#: pretix/plugins/paypal2/apps.py pretix/plugins/pretixdroid/apps.py
#: pretix/plugins/reports/apps.py pretix/plugins/returnurl/apps.py
#: pretix/plugins/sendmail/apps.py pretix/plugins/statistics/apps.py
#: pretix/plugins/stripe/apps.py pretix/plugins/ticketoutputpdf/apps.py
#: pretix/plugins/webcheckin/apps.py
msgid "the pretix team"
msgstr ""
@@ -27237,6 +27135,7 @@ msgstr ""
#: pretix/plugins/banktransfer/refund_export.py
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/control.html
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/import_assign.html
#: pretix/plugins/paypal/templates/pretixplugins/paypal/control.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control_legacy.html
msgid "Payer"
@@ -27730,7 +27629,8 @@ msgstr ""
msgid "Automatically checked in"
msgstr ""
#: pretix/plugins/checkinlists/exporters.py pretix/plugins/paypal2/payment.py
#: pretix/plugins/checkinlists/exporters.py pretix/plugins/paypal/payment.py
#: pretix/plugins/paypal2/payment.py
msgid "Secret"
msgstr ""
@@ -27789,6 +27689,152 @@ msgstr ""
msgid "A fully customizable payment method for manual processing."
msgstr ""
#: pretix/plugins/paypal/apps.py pretix/plugins/paypal/payment.py
#: pretix/plugins/paypal2/apps.py pretix/plugins/paypal2/payment.py
#: pretix/plugins/stripe/payment.py
msgid "PayPal"
msgstr ""
#: pretix/plugins/paypal/apps.py
msgid ""
"Accept payments with your PayPal account. PayPal is one of the most popular "
"payment methods world-wide."
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid ""
"The PayPal sandbox is being used, you can test without actually sending "
"money but you will need a PayPal sandbox user to log in."
msgstr ""
#: pretix/plugins/paypal/payment.py
msgid "PayPal account"
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid "Click here for a tutorial on how to obtain the required keys"
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
#: pretix/plugins/stripe/payment.py
msgid "Endpoint"
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid "Reference prefix"
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid ""
"Any value entered here will be added in front of the regular booking "
"reference containing the order number."
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid "Reference postfix"
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid ""
"Any value entered here will be added behind the regular booking reference "
"containing the order number."
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid "Disconnect from PayPal"
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid "We had trouble communicating with PayPal"
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid ""
"We were unable to process your payment. See below for details on how to "
"proceed."
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid ""
"PayPal has not yet approved the payment. We will inform you as soon as the "
"payment completed."
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
#, python-brace-format
msgid "Refunding the amount via PayPal failed: {}"
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid "The payment for this invoice has already been received."
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid "PayPal payment ID"
msgstr ""
#: pretix/plugins/paypal/payment.py pretix/plugins/paypal2/payment.py
msgid "PayPal sale ID"
msgstr ""
#: pretix/plugins/paypal/templates/pretixplugins/paypal/checkout_payment_confirm.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/checkout_payment_confirm.html
msgid ""
"The total amount listed above will be withdrawn from your PayPal account "
"after the confirmation of your purchase."
msgstr ""
#: pretix/plugins/paypal/templates/pretixplugins/paypal/checkout_payment_form.html
msgid ""
"After you clicked continue, we will redirect you to PayPal to fill in your "
"payment details. You will then be redirected back here to review and confirm "
"your order."
msgstr ""
#: pretix/plugins/paypal/templates/pretixplugins/paypal/control.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control_legacy.html
msgid "Sale ID"
msgstr ""
#: pretix/plugins/paypal/templates/pretixplugins/paypal/control.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control_legacy.html
msgid "Last update"
msgstr ""
#: pretix/plugins/paypal/templates/pretixplugins/paypal/control.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control_legacy.html
#: pretix/plugins/stripe/templates/pretixplugins/stripe/control.html
msgid "Total value"
msgstr ""
#: pretix/plugins/paypal/templates/pretixplugins/paypal/pending.html
msgid ""
"Our attempt to execute your Payment via PayPal has failed. Please try again "
"or contact us."
msgstr ""
#: pretix/plugins/paypal/templates/pretixplugins/paypal/pending.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/pending.html
msgid ""
"We're waiting for an answer from PayPal regarding your payment. Please "
"contact us, if this takes more than a few hours."
msgstr ""
#: pretix/plugins/paypal/views.py pretix/plugins/paypal2/views.py
msgid "Invalid response from PayPal received."
msgstr ""
#: pretix/plugins/paypal/views.py pretix/plugins/paypal2/views.py
msgid "It looks like you canceled the PayPal payment"
msgstr ""
#: pretix/plugins/paypal/views.py pretix/plugins/paypal2/views.py
msgid "Your PayPal account has been disconnected."
msgstr ""
#: pretix/plugins/paypal2/apps.py
msgid ""
"Accept payments with your PayPal account. In addition to regular PayPal "
@@ -27798,23 +27844,10 @@ msgid ""
"methods world-wide."
msgstr ""
#: pretix/plugins/paypal2/apps.py pretix/plugins/paypal2/payment.py
#: pretix/plugins/stripe/payment.py
msgid "PayPal"
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid "PayPal Merchant ID"
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid "Click here for a tutorial on how to obtain the required keys"
msgstr ""
#: pretix/plugins/paypal2/payment.py pretix/plugins/stripe/payment.py
msgid "Endpoint"
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid ""
"Even if a customer chooses an Alternative Payment Method, they will always "
@@ -27883,26 +27916,6 @@ msgid ""
"while the last payment is still under investigation."
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid "Reference prefix"
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid ""
"Any value entered here will be added in front of the regular booking "
"reference containing the order number."
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid "Reference postfix"
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid ""
"Any value entered here will be added behind the regular booking reference "
"containing the order number."
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid "-- Automatic --"
msgstr ""
@@ -27923,10 +27936,6 @@ msgstr ""
msgid "Connect with {icon} PayPal"
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid "Disconnect from PayPal"
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid ""
"Please configure a PayPal Webhook to the following endpoint in order to "
@@ -27955,12 +27964,6 @@ msgstr ""
msgid "An error occurred during connecting with PayPal, please try again."
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid ""
"The PayPal sandbox is being used, you can test without actually sending "
"money but you will need a PayPal sandbox user to log in."
msgstr ""
#: pretix/plugins/paypal2/payment.py
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/pending.html
msgid ""
@@ -27969,10 +27972,6 @@ msgid ""
"attempt. You can also try other payment methods, if available."
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid "We had trouble communicating with PayPal"
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid ""
"Something went wrong when requesting the payment status. Please try again."
@@ -27982,41 +27981,12 @@ msgstr ""
msgid "You may need to enable JavaScript for PayPal payments."
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid ""
"We were unable to process your payment. See below for details on how to "
"proceed."
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid ""
"PayPal has not yet approved the payment. We will inform you as soon as the "
"payment completed."
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid ""
"Refunding the amount via PayPal failed: The original payment does not "
"contain the required information to issue an automated refund."
msgstr ""
#: pretix/plugins/paypal2/payment.py
#, python-brace-format
msgid "Refunding the amount via PayPal failed: {}"
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid "The payment for this invoice has already been received."
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid "PayPal payment ID"
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid "PayPal sale ID"
msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid "PayPal APM"
msgstr ""
@@ -28104,12 +28074,6 @@ msgstr ""
msgid "We will then charge your PayPal account and finalize the order."
msgstr ""
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/checkout_payment_confirm.html
msgid ""
"The total amount listed above will be withdrawn from your PayPal account "
"after the confirmation of your purchase."
msgstr ""
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/checkout_payment_confirm.html
msgid ""
"After placing your order, you will be able to select your desired payment "
@@ -28141,11 +28105,6 @@ msgid ""
"different payment method, if you prefer."
msgstr ""
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control_legacy.html
msgid "Sale ID"
msgstr ""
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control.html
msgid "Capture status"
msgstr ""
@@ -28156,17 +28115,6 @@ msgid ""
"money will not be disbursed and the order remain in its pending state."
msgstr ""
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control_legacy.html
msgid "Last update"
msgstr ""
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control.html
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control_legacy.html
#: pretix/plugins/stripe/templates/pretixplugins/stripe/control.html
msgid "Total value"
msgstr ""
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/pay.html
#: pretix/plugins/stripe/templates/pretixplugins/stripe/sca.html
#: pretix/plugins/stripe/templates/pretixplugins/stripe/sca_return.html
@@ -28200,12 +28148,6 @@ msgid ""
"to resolve this case."
msgstr ""
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/pending.html
msgid ""
"We're waiting for an answer from PayPal regarding your payment. Please "
"contact us, if this takes more than a few hours."
msgstr ""
#: pretix/plugins/paypal2/views.py
msgid ""
"An error occurred returning from PayPal: request parameters missing. Please "
@@ -28236,18 +28178,6 @@ msgid ""
"in detail below."
msgstr ""
#: pretix/plugins/paypal2/views.py
msgid "Invalid response from PayPal received."
msgstr ""
#: pretix/plugins/paypal2/views.py
msgid "It looks like you canceled the PayPal payment"
msgstr ""
#: pretix/plugins/paypal2/views.py
msgid "Your PayPal account has been disconnected."
msgstr ""
#: pretix/plugins/pretixdroid/apps.py
msgid "Old check-in device API"
msgstr ""
@@ -30267,6 +30197,7 @@ msgstr ""
#: pretix/presale/forms/order.py
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
msgid "plus taxes"
msgstr ""
@@ -30687,31 +30618,6 @@ msgid ""
"Please go to the payment settings and activate one or more payment providers."
msgstr ""
#: pretix/presale/templates/pretixpresale/event/checkout_payment.html
msgid ""
"Not sure yet? You can complete your order first and then select a payment "
"method later."
msgstr ""
#: pretix/presale/templates/pretixpresale/event/checkout_payment.html
msgid ""
"To do so, please first remove the payment methods you already selected above."
msgstr ""
#: pretix/presale/templates/pretixpresale/event/checkout_payment.html
#, python-format
msgid "Your payment needs to be completed within %(minutes)s minutes."
msgstr ""
#: pretix/presale/templates/pretixpresale/event/checkout_payment.html
#, python-format
msgid "Your payment needs to be completed by %(deadline)s."
msgstr ""
#: pretix/presale/templates/pretixpresale/event/checkout_payment.html
msgid "Proceed without selection"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/checkout_questions.html
msgid "Before we continue, we need you to answer some questions."
msgstr ""
@@ -30778,12 +30684,14 @@ msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
#, python-format
msgid "minimum amount to order: %(num)s"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
msgctxt "price"
msgid "free"
msgstr ""
@@ -30812,56 +30720,66 @@ msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
msgid "Original price:"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
msgid "New price:"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
#, python-format
msgid "Modify price for %(item)s, at least %(price)s"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
#, python-format
msgid "Modify price for %(item)s"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
msgid "incl. taxes"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
#, python-format
msgid "<strong>plus</strong> %(rate)s%% %(name)s"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
#, python-format
msgid "incl. %(rate)s%% %(name)s"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
msgctxt "checkbox"
msgid "Select"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
msgid "Decrease quantity"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
msgid "Increase quantity"
msgstr ""
@@ -31322,10 +31240,12 @@ msgid "Your order qualifies for a discount"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
msgid "Uncategorized items"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
#, python-format
msgid "Show full-size image of %(item)s"
msgstr ""
@@ -31338,16 +31258,19 @@ msgstr[0] ""
msgstr[1] ""
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
#, python-format
msgid "%(value)s incl. taxes"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
#, python-format
msgid "%(value)s without taxes"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html
#: pretix/presale/templates/pretixpresale/event/voucher.html
#, python-format
msgid "Set price in %(currency)s for %(item)s"
msgstr ""
@@ -32006,6 +31929,11 @@ msgid ""
"products at the specified price:"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/voucher.html
#, python-format
msgid "from %(minprice)s"
msgstr ""
#: pretix/presale/templates/pretixpresale/event/voucher.html
#, python-format
msgid "You need to select at least %(number)s products."
+84 -1
View File
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-30 07:26+0000\n"
"POT-Creation-Date: 2026-07-06 15:52+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"
@@ -766,163 +766,194 @@ msgstr ""
msgid "Google Pay"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Quantity"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Decrease quantity"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Increase quantity"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Filter events by"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Filter"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Price"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "Original price: %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "New price: %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Select"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "Select %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "Select variant %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Sold out"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Buy"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Register"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Reserved"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "FREE"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "from %(currency)s %(price)s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "Image of %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "incl. %(rate)s% %(taxname)s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "plus %(rate)s% %(taxname)s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "incl. taxes"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "plus taxes"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "currently available: %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Only available with a voucher"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Not yet available"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Not available anymore"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Currently not available"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "minimum amount to order: %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Close ticket shop"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "The ticket shop could not be loaded."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid ""
@@ -930,21 +961,25 @@ msgid ""
"in a new tab to continue."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Open ticket shop"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Checkout"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "The cart could not be created. Please try again later"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid ""
@@ -952,11 +987,13 @@ msgid ""
"this ticket shop. Please click \"Continue\" to retry in a new tab."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Waiting list"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid ""
@@ -964,96 +1001,115 @@ msgid ""
"products, they will be added to your existing cart."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Resume checkout"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Redeem a voucher"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Redeem"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Voucher code"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Close"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Close checkout"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "You cannot cancel this operation. Please wait for loading to finish."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Continue"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Show variants"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Hide variants"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Choose a different event"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Choose a different date"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Back"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Next month"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Previous month"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Next week"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Previous week"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Open seat selection"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid ""
@@ -1062,111 +1118,138 @@ msgid ""
"again."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Load more"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Mo"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Tu"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "We"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Th"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Fr"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Sa"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Su"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Monday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Tuesday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Wednesday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Thursday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Friday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Saturday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Sunday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "January"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "February"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "March"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "April"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "May"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "June"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "July"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "August"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "September"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "October"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "November"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "December"
msgstr ""
File diff suppressed because it is too large Load Diff
+84 -1
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-30 07:26+0000\n"
"POT-Creation-Date: 2026-07-06 15:52+0000\n"
"PO-Revision-Date: 2025-10-31 17:00+0000\n"
"Last-Translator: Núria Masclans <nuriamasclansserrat@gmail.com>\n"
"Language-Team: Catalan <https://translate.pretix.eu/projects/pretix/pretix-"
@@ -787,163 +787,194 @@ msgstr "La teva hora local:"
msgid "Google Pay"
msgstr "Google Pay"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Quantity"
msgstr "Quantitat"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Decrease quantity"
msgstr "Disminueix quantitat"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Increase quantity"
msgstr "Augmenta quantitat"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Filter events by"
msgstr "Filtra els esdeveniments per"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Filter"
msgstr "Filtra"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Price"
msgstr "Preu"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "Original price: %s"
msgstr "Preu original: %s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "New price: %s"
msgstr "Nou preu: %s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Select"
msgstr "Selecciona"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "Select %s"
msgstr "Selecciona %s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "Select variant %s"
msgstr "Selecciona la variant %s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Sold out"
msgstr "Esgotat"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Buy"
msgstr "Compra"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Register"
msgstr "Registrar-vos"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Reserved"
msgstr "Reservat"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "FREE"
msgstr "GRATUÏT"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "from %(currency)s %(price)s"
msgstr "des de %(price)s %(currency)s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "Image of %s"
msgstr "Imatge de %s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "incl. %(rate)s% %(taxname)s"
msgstr "Inclòs %(rate)s% %(taxname)s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "plus %(rate)s% %(taxname)s"
msgstr "més %(rate)s% %(taxname)s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "incl. taxes"
msgstr "incl. impostos"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "plus taxes"
msgstr "més impostos"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "currently available: %s"
msgstr "disponibles: %s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Only available with a voucher"
msgstr "Només disponible amb un cupó"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Not yet available"
msgstr "Encara no disponible"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Not available anymore"
msgstr "Ja no està disponible"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Currently not available"
msgstr "No disponible"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "minimum amount to order: %s"
msgstr "Comanda mínima: %s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Close ticket shop"
msgstr "Tanca la botiga d'entrades"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "The ticket shop could not be loaded."
msgstr "No s'ha pogut carregar la botiga d'entrades."
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid ""
@@ -951,21 +982,25 @@ msgid ""
"in a new tab to continue."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Open ticket shop"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Checkout"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "The cart could not be created. Please try again later"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid ""
@@ -973,11 +1008,13 @@ msgid ""
"this ticket shop. Please click \"Continue\" to retry in a new tab."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Waiting list"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid ""
@@ -985,96 +1022,115 @@ msgid ""
"products, they will be added to your existing cart."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Resume checkout"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Redeem a voucher"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Redeem"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Voucher code"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Close"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Close checkout"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "You cannot cancel this operation. Please wait for loading to finish."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Continue"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Show variants"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Hide variants"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Choose a different event"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Choose a different date"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Back"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Next month"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Previous month"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Next week"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Previous week"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Open seat selection"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid ""
@@ -1083,111 +1139,138 @@ msgid ""
"again."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Load more"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Mo"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Tu"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "We"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Th"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Fr"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Sa"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Su"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Monday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Tuesday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Wednesday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Thursday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Friday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Saturday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Sunday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "January"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "February"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "March"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "April"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "May"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "June"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "July"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "August"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "September"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "October"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "November"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "December"
msgstr ""
File diff suppressed because it is too large Load Diff
+84 -1
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-30 07:26+0000\n"
"POT-Creation-Date: 2026-07-06 15:52+0000\n"
"PO-Revision-Date: 2026-01-08 04:00+0000\n"
"Last-Translator: Jiří Pastrňák <jiri@pastrnak.email>\n"
"Language-Team: Czech <https://translate.pretix.eu/projects/pretix/pretix-js/"
@@ -801,163 +801,194 @@ msgstr "Místní čas:"
msgid "Google Pay"
msgstr "Google Pay"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Quantity"
msgstr "Počet"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Decrease quantity"
msgstr "Snížit počet"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Increase quantity"
msgstr "Zvýšit počet"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Filter events by"
msgstr "Filtrovat události"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Filter"
msgstr "Filtrovat"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Price"
msgstr "Cena"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "Original price: %s"
msgstr "Původní cena: %s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "New price: %s"
msgstr "Nová cena: %s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Select"
msgstr "Vybrat"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "Select %s"
msgstr "Vybrat %s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "Select variant %s"
msgstr "Vybrat variantu %s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Sold out"
msgstr "Vyprodáno"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Buy"
msgstr "Koupit"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Register"
msgstr "Zaregistrovat"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Reserved"
msgstr "Rezervováno"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "FREE"
msgstr "ZDARMA"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "from %(currency)s %(price)s"
msgstr "od %(currency)s %(price)s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "Image of %s"
msgstr "Obrázek%s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "incl. %(rate)s% %(taxname)s"
msgstr "včetně %(rate)s% %(taxname)s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "plus %(rate)s% %(taxname)s"
msgstr "plus %(rate)s% %(taxname)s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "incl. taxes"
msgstr "včetně daní"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "plus taxes"
msgstr "plus daně"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "currently available: %s"
msgstr "aktuálně k dispozici: %s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Only available with a voucher"
msgstr "K dispozici pouze s poukazem"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Not yet available"
msgstr "Zatím není k dispozici"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Not available anymore"
msgstr "Již není k dispozici"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Currently not available"
msgstr "Momentálně není k dispozici"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "minimum amount to order: %s"
msgstr "minimální množství pro objednávku: %s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Close ticket shop"
msgstr "Zavřít obchod"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "The ticket shop could not be loaded."
msgstr "Obchod vstupenek nemohl být načten."
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid ""
@@ -967,21 +998,25 @@ msgstr ""
"V současné době je v tomto obchodě s vstupenkami mnoho uživatelů. Otevřete "
"prosím obchod v nové kartě."
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Open ticket shop"
msgstr "Obchod vstupenek otevřit"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Checkout"
msgstr "Přejít k platbě"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "The cart could not be created. Please try again later"
msgstr "Nákupní košík se nepodařilo vytvořit. Zkuste to prosím znovu"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid ""
@@ -992,11 +1027,13 @@ msgstr ""
"mnoho uživatelů. Klikněte prosím na \"Pokračovat\" a zkuste to znovu na nové "
"kartě."
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Waiting list"
msgstr "Čekací listina"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid ""
@@ -1006,31 +1043,37 @@ msgstr ""
"V současné době máte aktivní košík pro tuto událost. Pokud vyberete další "
"produkty, budou přidány do vašeho košíku."
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Resume checkout"
msgstr "Obnovit checkout"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Redeem a voucher"
msgstr "Uplatnit poukázku"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Redeem"
msgstr "Uplatnit"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Voucher code"
msgstr "Kód poukázky"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Close"
msgstr "Zavřít"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, fuzzy
#| msgctxt "widget"
@@ -1039,66 +1082,79 @@ msgctxt "widget"
msgid "Close checkout"
msgstr "Obnovit checkout"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "You cannot cancel this operation. Please wait for loading to finish."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Continue"
msgstr "Pokračovat"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Show variants"
msgstr "Zobrazit možnosti"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Hide variants"
msgstr "Skrýt možnosti"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Choose a different event"
msgstr "Vybrat jinou událost"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Choose a different date"
msgstr "Vybrat jiný datum"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Back"
msgstr "Zpět"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Next month"
msgstr "Následující měsíc"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Previous month"
msgstr "Předchozí měsíc"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Next week"
msgstr "Příští týden"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Previous week"
msgstr "Předchozí týden"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Open seat selection"
msgstr "Otevřete výběr míst"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid ""
@@ -1110,111 +1166,138 @@ msgstr ""
"Pokud chcete, můžete se přidat na čekací listinu. Poté vás budeme "
"informovat, pokud budou místa opět volná."
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Load more"
msgstr "Načíst více"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Mo"
msgstr "Po"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Tu"
msgstr "Út"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "We"
msgstr "St"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Th"
msgstr "Čt"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Fr"
msgstr "Pá"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Sa"
msgstr "So"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Su"
msgstr "Ne"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Monday"
msgstr "Pondělí"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Tuesday"
msgstr "Úterý"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Wednesday"
msgstr "Středa"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Thursday"
msgstr "Čtvrtek"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Friday"
msgstr "Pátek"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Saturday"
msgstr "Sobota"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Sunday"
msgstr "Neděle"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "January"
msgstr "Leden"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "February"
msgstr "Únor"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "March"
msgstr "Březen"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "April"
msgstr "Duben"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "May"
msgstr "Květen"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "June"
msgstr "červen"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "July"
msgstr "Červenec"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "August"
msgstr "Srpen"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "September"
msgstr "Září"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "October"
msgstr "Říjen"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "November"
msgstr "Listopad"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "December"
msgstr "Prosinec"
File diff suppressed because it is too large Load Diff
+84 -1
View File
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-30 07:26+0000\n"
"POT-Creation-Date: 2026-07-06 15:52+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"
@@ -767,163 +767,194 @@ msgstr ""
msgid "Google Pay"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Quantity"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Decrease quantity"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Increase quantity"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Filter events by"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Filter"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Price"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "Original price: %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "New price: %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Select"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "Select %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "Select variant %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Sold out"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Buy"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Register"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Reserved"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "FREE"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "from %(currency)s %(price)s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "Image of %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "incl. %(rate)s% %(taxname)s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "plus %(rate)s% %(taxname)s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "incl. taxes"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "plus taxes"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "currently available: %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Only available with a voucher"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Not yet available"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Not available anymore"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Currently not available"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "minimum amount to order: %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Close ticket shop"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "The ticket shop could not be loaded."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid ""
@@ -931,21 +962,25 @@ msgid ""
"in a new tab to continue."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Open ticket shop"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Checkout"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "The cart could not be created. Please try again later"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid ""
@@ -953,11 +988,13 @@ msgid ""
"this ticket shop. Please click \"Continue\" to retry in a new tab."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Waiting list"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid ""
@@ -965,96 +1002,115 @@ msgid ""
"products, they will be added to your existing cart."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Resume checkout"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Redeem a voucher"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Redeem"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Voucher code"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Close"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Close checkout"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "You cannot cancel this operation. Please wait for loading to finish."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Continue"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Show variants"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Hide variants"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Choose a different event"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Choose a different date"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Back"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Next month"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Previous month"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Next week"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Previous week"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Open seat selection"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid ""
@@ -1063,111 +1119,138 @@ msgid ""
"again."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Load more"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Mo"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Tu"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "We"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Th"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Fr"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Sa"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Su"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Monday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Tuesday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Wednesday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Thursday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Friday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Saturday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Sunday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "January"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "February"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "March"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "April"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "May"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "June"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "July"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "August"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "September"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "October"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "November"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "December"
msgstr ""
File diff suppressed because it is too large Load Diff
+84 -1
View File
@@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-30 07:26+0000\n"
"POT-Creation-Date: 2026-07-06 15:52+0000\n"
"PO-Revision-Date: 2026-07-31 18:00+0000\n"
"Last-Translator: Nikolai <nikolai@lengefeldt.de>\n"
"Language-Team: Danish <https://translate.pretix.eu/projects/pretix/pretix-js/"
@@ -848,59 +848,70 @@ msgstr "Din lokaltid:"
msgid "Google Pay"
msgstr "Apple Pay"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Quantity"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Decrease quantity"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Increase quantity"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Filter events by"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Filter"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Price"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "Original price: %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "New price: %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Select"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "Select %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, fuzzy, javascript-format
#| msgctxt "widget"
@@ -909,73 +920,87 @@ msgctxt "widget"
msgid "Select variant %s"
msgstr "Vis varianter"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Sold out"
msgstr "Udsolgt"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Buy"
msgstr "Læg i kurv"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Register"
msgstr "Book nu"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Reserved"
msgstr "Reserveret"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "FREE"
msgstr "GRATIS"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "from %(currency)s %(price)s"
msgstr "fra %(currency)s %(price)s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "Image of %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "incl. %(rate)s% %(taxname)s"
msgstr "inkl. %(rate)s% %(taxname)s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "plus %(rate)s% %(taxname)s"
msgstr "plus %(rate)s% %(taxname)s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "incl. taxes"
msgstr "inkl. moms"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "plus taxes"
msgstr "plus moms"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "currently available: %s"
msgstr "tilgængelig: %s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Only available with a voucher"
msgstr "Kun tilgængelig med en rabatkode"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, fuzzy
#| msgid "Payment method unavailable"
@@ -983,11 +1008,13 @@ msgctxt "widget"
msgid "Not yet available"
msgstr "Betalingsmetode er ikke tilgængelig"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Not available anymore"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, fuzzy
#| msgctxt "widget"
@@ -996,22 +1023,26 @@ msgctxt "widget"
msgid "Currently not available"
msgstr "tilgængelig: %s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "minimum amount to order: %s"
msgstr "minimumsantal: %s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Close ticket shop"
msgstr "Luk billetbutik"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "The ticket shop could not be loaded."
msgstr "Billetbutikken kunne ikke hentes."
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid ""
@@ -1019,6 +1050,7 @@ msgid ""
"in a new tab to continue."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, fuzzy
#| msgctxt "widget"
@@ -1027,6 +1059,7 @@ msgctxt "widget"
msgid "Open ticket shop"
msgstr "Luk billetbutik"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, fuzzy
#| msgctxt "widget"
@@ -1035,11 +1068,13 @@ msgctxt "widget"
msgid "Checkout"
msgstr "Fortsæt booking"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "The cart could not be created. Please try again later"
msgstr "Kurven kunne ikke oprettes. Prøv igen senere"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid ""
@@ -1047,11 +1082,13 @@ msgid ""
"this ticket shop. Please click \"Continue\" to retry in a new tab."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Waiting list"
msgstr "Venteliste"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid ""
@@ -1061,31 +1098,37 @@ msgstr ""
"Du har allerede en aktiv booking i gang for dette arrangement. Hvis du "
"vælger flere produkter, så vil de blive tilføjet din eksisterende booking."
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Resume checkout"
msgstr "Fortsæt booking"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Redeem a voucher"
msgstr "Indløs rabatkode"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Redeem"
msgstr "Indløs"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Voucher code"
msgstr "Rabatkode"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Close"
msgstr "Luk"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, fuzzy
#| msgctxt "widget"
@@ -1094,16 +1137,19 @@ msgctxt "widget"
msgid "Close checkout"
msgstr "Fortsæt booking"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "You cannot cancel this operation. Please wait for loading to finish."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Continue"
msgstr "Fortsæt"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, fuzzy
#| msgctxt "widget"
@@ -1112,6 +1158,7 @@ msgctxt "widget"
msgid "Show variants"
msgstr "Vis varianter"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, fuzzy
#| msgctxt "widget"
@@ -1120,36 +1167,43 @@ msgctxt "widget"
msgid "Hide variants"
msgstr "Vis varianter"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Choose a different event"
msgstr "Vælg et andet arrangement"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Choose a different date"
msgstr "Vælg en anden dato"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Back"
msgstr "Tilbage"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Next month"
msgstr "Næste måned"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Previous month"
msgstr "Forrige måned"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Next week"
msgstr "Næste uge"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, fuzzy
#| msgctxt "widget"
@@ -1158,11 +1212,13 @@ msgctxt "widget"
msgid "Previous week"
msgstr "Forrige måned"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Open seat selection"
msgstr "Åbn sædevalg"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid ""
@@ -1171,111 +1227,138 @@ msgid ""
"again."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Load more"
msgstr "Hent flere"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Mo"
msgstr "Man"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Tu"
msgstr "Tirs"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "We"
msgstr "Ons"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Th"
msgstr "Tors"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Fr"
msgstr "Fre"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Sa"
msgstr "Lør"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Su"
msgstr "Søn"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Monday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Tuesday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Wednesday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Thursday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Friday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Saturday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Sunday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "January"
msgstr "januar"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "February"
msgstr "februar"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "March"
msgstr "marts"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "April"
msgstr "april"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "May"
msgstr "maj"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "June"
msgstr "juni"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "July"
msgstr "juli"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "August"
msgstr "august"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "September"
msgstr "september"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "October"
msgstr "oktober"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "November"
msgstr "november"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "December"
msgstr "december"
File diff suppressed because it is too large Load Diff
+84 -1
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-09-30 07:26+0000\n"
"POT-Creation-Date: 2026-07-06 15:52+0000\n"
"PO-Revision-Date: 2026-07-06 02:00+0000\n"
"Last-Translator: Benedikt Bormann <mail@bbormann.de>\n"
"Language-Team: German <https://translate.pretix.eu/projects/pretix/pretix-js/"
@@ -800,163 +800,194 @@ msgstr "Deine lokale Zeit:"
msgid "Google Pay"
msgstr "Google Pay"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Quantity"
msgstr "Menge"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Decrease quantity"
msgstr "Menge reduzieren"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Increase quantity"
msgstr "Menge erhöhen"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Filter events by"
msgstr "Veranstaltungen filtern nach"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Filter"
msgstr "Filtern"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Price"
msgstr "Preis"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "Original price: %s"
msgstr "Originalpreis: %s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "New price: %s"
msgstr "Neuer Preis: %s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Select"
msgstr "Auswählen"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "Select %s"
msgstr "%s auswählen"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "Select variant %s"
msgstr "Variante %s auswählen"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Sold out"
msgstr "Ausverkauft"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Buy"
msgstr "In den Warenkorb"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Register"
msgstr "Anmelden"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Reserved"
msgstr "Reserviert"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "FREE"
msgstr "GRATIS"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "from %(currency)s %(price)s"
msgstr "ab %(currency)s %(price)s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "Image of %s"
msgstr "Bild von %s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "incl. %(rate)s% %(taxname)s"
msgstr "inkl. %(rate)s% %(taxname)s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "plus %(rate)s% %(taxname)s"
msgstr "zzgl. %(rate)s% %(taxname)s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "incl. taxes"
msgstr "inkl. Steuern"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "plus taxes"
msgstr "zzgl. Steuern"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "currently available: %s"
msgstr "aktuell verfügbar: %s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Only available with a voucher"
msgstr "Nur mit Gutschein verfügbar"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Not yet available"
msgstr "Noch nicht verfügbar"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Not available anymore"
msgstr "Nicht mehr verfügbar"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Currently not available"
msgstr "Aktuell nicht verfügbar"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "minimum amount to order: %s"
msgstr "minimale Bestellmenge: %s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Close ticket shop"
msgstr "Ticketshop schließen"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "The ticket shop could not be loaded."
msgstr "Der Ticketshop konnte nicht geladen werden."
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid ""
@@ -966,21 +997,25 @@ msgstr ""
"Es sind derzeit sehr viele Benutzer in diesem Ticketshop. Bitte öffnen Sie "
"diesen Ticketshop in einem neuen Tab um fortzufahren."
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Open ticket shop"
msgstr "Ticketshop öffnen"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Checkout"
msgstr "Buchung"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "The cart could not be created. Please try again later"
msgstr "Der Warenkorb konnte nicht erstellt werden. Bitte erneut versuchen"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid ""
@@ -991,11 +1026,13 @@ msgstr ""
"diesem Ticketshop sind. Bitte klicken Sie \"Weiter\" um es in einem neuen "
"Tab erneut zu versuchen."
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Waiting list"
msgstr "Warteliste"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid ""
@@ -1005,36 +1042,43 @@ msgstr ""
"Sie haben einen aktiven Warenkorb für diese Veranstaltung. Wenn Sie mehr "
"Produkte auswählen, werden diese zu Ihrem Warenkorb hinzugefügt."
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Resume checkout"
msgstr "Kauf fortsetzen"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Redeem a voucher"
msgstr "Gutschein einlösen"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Redeem"
msgstr "Einlösen"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Voucher code"
msgstr "Gutscheincode"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Close"
msgstr "Schließen"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Close checkout"
msgstr "Kauf schließen"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "You cannot cancel this operation. Please wait for loading to finish."
@@ -1042,61 +1086,73 @@ msgstr ""
"Sie können diese Aktion nicht abbrechen. Bitte warten Sie, bis der "
"Ladevorgang abgeschlossen ist."
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Continue"
msgstr "Fortfahren"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Show variants"
msgstr "Varianten zeigen"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Hide variants"
msgstr "Varianten verstecken"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Choose a different event"
msgstr "Andere Veranstaltung auswählen"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Choose a different date"
msgstr "Anderen Termin auswählen"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Back"
msgstr "Zurück"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Next month"
msgstr "Nächster Monat"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Previous month"
msgstr "Vorheriger Monat"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Next week"
msgstr "Nächste Woche"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Previous week"
msgstr "Vorherige Woche"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Open seat selection"
msgstr "Sitzplan öffnen"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid ""
@@ -1108,111 +1164,138 @@ msgstr ""
"möchten, können Sie sich in die Warteliste eintragen. Wir benachrichtigen "
"Sie dann, wenn die gewünschten Plätze wieder verfügbar sind."
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Load more"
msgstr "Mehr laden"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Mo"
msgstr "Mo"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Tu"
msgstr "Di"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "We"
msgstr "Mi"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Th"
msgstr "Do"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Fr"
msgstr "Fr"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Sa"
msgstr "Sa"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Su"
msgstr "So"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Monday"
msgstr "Montag"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Tuesday"
msgstr "Dienstag"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Wednesday"
msgstr "Mittwoch"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Thursday"
msgstr "Donnerstag"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Friday"
msgstr "Freitag"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Saturday"
msgstr "Samstag"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Sunday"
msgstr "Sonntag"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "January"
msgstr "Januar"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "February"
msgstr "Februar"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "March"
msgstr "März"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "April"
msgstr "April"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "May"
msgstr "Mai"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "June"
msgstr "Juni"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "July"
msgstr "Juli"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "August"
msgstr "August"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "September"
msgstr "September"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "October"
msgstr "Oktober"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "November"
msgstr "November"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "December"
msgstr "Dezember"
-1
View File
@@ -159,7 +159,6 @@ Erstattungsstatus
Erstattungsweg
erstmalig
etc
EU-USt-ID
EU-USt-ID-Nr
Event
Event-Absage
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: 2026-09-30 07:26+0000\n"
"POT-Creation-Date: 2026-07-06 15:52+0000\n"
"PO-Revision-Date: 2026-07-13 11:28+0000\n"
"Last-Translator: Raphael Michel <michel@rami.io>\n"
"Language-Team: German (informal) <https://translate.pretix.eu/projects/"
@@ -799,163 +799,194 @@ msgstr "Deine lokale Zeit:"
msgid "Google Pay"
msgstr "Google Pay"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Quantity"
msgstr "Menge"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Decrease quantity"
msgstr "Menge reduzieren"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Increase quantity"
msgstr "Menge erhöhen"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Filter events by"
msgstr "Veranstaltungen filtern nach"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Filter"
msgstr "Filtern"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Price"
msgstr "Preis"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "Original price: %s"
msgstr "Originalpreis: %s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "New price: %s"
msgstr "Neuer Preis: %s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Select"
msgstr "Auswählen"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "Select %s"
msgstr "%s auswählen"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "Select variant %s"
msgstr "Variante %s auswählen"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Sold out"
msgstr "Ausverkauft"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Buy"
msgstr "In den Warenkorb"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Register"
msgstr "Anmelden"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Reserved"
msgstr "Reserviert"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "FREE"
msgstr "GRATIS"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "from %(currency)s %(price)s"
msgstr "ab %(currency)s %(price)s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "Image of %s"
msgstr "Bild von %s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "incl. %(rate)s% %(taxname)s"
msgstr "inkl. %(rate)s% %(taxname)s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "plus %(rate)s% %(taxname)s"
msgstr "zzgl. %(rate)s% %(taxname)s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "incl. taxes"
msgstr "inkl. Steuern"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "plus taxes"
msgstr "zzgl. Steuern"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "currently available: %s"
msgstr "aktuell verfügbar: %s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Only available with a voucher"
msgstr "Nur mit Gutschein verfügbar"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Not yet available"
msgstr "Noch nicht verfügbar"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Not available anymore"
msgstr "Nicht mehr verfügbar"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Currently not available"
msgstr "Aktuell nicht verfügbar"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
#, javascript-format
msgctxt "widget"
msgid "minimum amount to order: %s"
msgstr "minimale Bestellmenge: %s"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Close ticket shop"
msgstr "Ticketshop schließen"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "The ticket shop could not be loaded."
msgstr "Der Ticketshop konnte nicht geladen werden."
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid ""
@@ -965,21 +996,25 @@ msgstr ""
"Es sind derzeit sehr viele Benutzer in diesem Ticketshop. Bitte öffne diesen "
"Ticketshop in einem neuen Tab um fortzufahren."
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Open ticket shop"
msgstr "Ticketshop öffnen"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Checkout"
msgstr "Buchung"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "The cart could not be created. Please try again later"
msgstr "Der Warenkorb konnte nicht erstellt werden. Bitte erneut versuchen."
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid ""
@@ -990,11 +1025,13 @@ msgstr ""
"diesem Ticketshop sind. Bitte klicke \"Weiter\" um es in einem neuen Tab "
"erneut zu versuchen."
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Waiting list"
msgstr "Warteliste"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid ""
@@ -1004,36 +1041,43 @@ msgstr ""
"Du hast einen aktiven Warenkorb für diese Veranstaltung. Wenn du mehr "
"Produkte auswählst, werden diese zu deinem Warenkorb hinzugefügt."
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Resume checkout"
msgstr "Kauf fortsetzen"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Redeem a voucher"
msgstr "Gutschein einlösen"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Redeem"
msgstr "Einlösen"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Voucher code"
msgstr "Gutscheincode"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Close"
msgstr "Schließen"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Close checkout"
msgstr "Kauf schließen"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "You cannot cancel this operation. Please wait for loading to finish."
@@ -1041,61 +1085,73 @@ msgstr ""
"Du kannst diese Aktion nicht abbrechen. Bitte warte, bis der Ladevorgang "
"abgeschlossen ist."
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Continue"
msgstr "Fortfahren"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Show variants"
msgstr "Varianten zeigen"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Hide variants"
msgstr "Varianten verstecken"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Choose a different event"
msgstr "Andere Veranstaltung auswählen"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Choose a different date"
msgstr "Anderen Termin auswählen"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Back"
msgstr "Zurück"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Next month"
msgstr "Nächster Monat"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Previous month"
msgstr "Vorheriger Monat"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Next week"
msgstr "Nächste Woche"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Previous week"
msgstr "Vorherige Woche"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Open seat selection"
msgstr "Sitzplan öffnen"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid ""
@@ -1107,111 +1163,138 @@ msgstr ""
"möchtest, kannst du dich in die Warteliste eintragen. Wir benachrichtigen "
"dich dann, wenn die gewünschten Plätze wieder verfügbar sind."
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgctxt "widget"
msgid "Load more"
msgstr "Mehr laden"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Mo"
msgstr "Mo"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Tu"
msgstr "Di"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "We"
msgstr "Mi"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Th"
msgstr "Do"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Fr"
msgstr "Fr"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Sa"
msgstr "Sa"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Su"
msgstr "So"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Monday"
msgstr "Montag"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Tuesday"
msgstr "Dienstag"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Wednesday"
msgstr "Mittwoch"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Thursday"
msgstr "Donnerstag"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Friday"
msgstr "Freitag"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Saturday"
msgstr "Samstag"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "Sunday"
msgstr "Sonntag"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "January"
msgstr "Januar"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "February"
msgstr "Februar"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "March"
msgstr "März"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "April"
msgstr "April"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "May"
msgstr "Mai"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "June"
msgstr "Juni"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "July"
msgstr "Juli"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "August"
msgstr "August"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "September"
msgstr "September"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "October"
msgstr "Oktober"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "November"
msgstr "November"
#: pretix/static/pretixpresale/js/widget/widget.js
#: pretix/static/pretixpresale/widget/src/i18n.ts
msgid "December"
msgstr "Dezember"
@@ -159,7 +159,6 @@ Erstattungsstatus
Erstattungsweg
erstmalig
etc
EU-USt-ID
EU-USt-ID-Nr
Event
Event-Absage

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