Compare commits

...

273 Commits

Author SHA1 Message Date
Richard Schreiber e0dec71262 add comment why onblur is needed 2025-05-06 13:04:46 +02:00
Richard Schreiber 4950ba8d03 add has-error for coloring error-messages 2025-05-06 13:00:14 +02:00
Richard Schreiber 6aab808b8d add permanent role=alert to label 2025-05-06 12:15:06 +02:00
Richard Schreiber 47bc015d98 draft push for weekend 2025-05-06 09:28:56 +02:00
Richard Schreiber 2605fe93d9 Fix unhandled error when parsing date in calendar-view (#5072) 2025-05-05 15:33:22 +02:00
Richard Schreiber 3dedfd6ee0 [A11y] fix tablist issues (#5060) 2025-05-05 12:16:04 +02:00
Richard Schreiber f71eb195c4 [A11y] Fix service fee HTML-structure (#5046) 2025-05-05 11:59:17 +02:00
Richard Schreiber f09e9590a8 [A11y] make text "required" visible in labels (#5042) 2025-05-05 11:40:35 +02:00
Richard Schreiber c53d44238c [A11y] Improve voice-control access for quantity rocker-buttons 2025-05-05 10:08:17 +02:00
Raphael Michel 3bcc504bd8 Geocoding utils: Support more flexible set of input fields (#5025) 2025-05-02 18:06:13 +02:00
dependabot[bot] d802f747c7 Bump @babel/core from 7.26.10 to 7.27.1 in /src/pretix/static/npm_dir
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.26.10 to 7.27.1.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.27.1/packages/babel-core)

---
updated-dependencies:
- dependency-name: "@babel/core"
  dependency-version: 7.27.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-02 11:46:21 +02:00
luelista d926030bf6 Event list: fix parsing of date query parameter (#5047)
Use the same localization formats as used when generating the value
2025-05-02 10:22:04 +02:00
dependabot[bot] 1e4c577b31 Bump qrcode from 8.1 to 8.2
Bumps [qrcode](https://github.com/lincolnloop/python-qrcode) from 8.1 to 8.2.
- [Changelog](https://github.com/lincolnloop/python-qrcode/blob/main/CHANGES.rst)
- [Commits](https://github.com/lincolnloop/python-qrcode/commits/v8.2)

---
updated-dependencies:
- dependency-name: qrcode
  dependency-version: '8.2'
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-02 10:16:18 +02:00
dependabot[bot] 8cae00941a Bump @babel/preset-env in /src/pretix/static/npm_dir
Bumps [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env) from 7.26.9 to 7.27.1.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.27.1/packages/babel-preset-env)

---
updated-dependencies:
- dependency-name: "@babel/preset-env"
  dependency-version: 7.27.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-02 10:16:03 +02:00
dependabot[bot] 602287b3ec Update sentry-sdk requirement from ==2.25.* to ==2.27.*
Updates the requirements on [sentry-sdk](https://github.com/getsentry/sentry-python) to permit the latest version.
- [Release notes](https://github.com/getsentry/sentry-python/releases)
- [Changelog](https://github.com/getsentry/sentry-python/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-python/compare/2.25.0...2.27.0)

---
updated-dependencies:
- dependency-name: sentry-sdk
  dependency-version: 2.27.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-30 12:47:59 +02:00
CVZ-es 817f17dac5 Translations: Update Spanish
Currently translated at 100.0% (244 of 244 strings)

Translation: pretix/pretix (JavaScript parts)
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix-js/es/

powered by weblate
2025-04-30 12:47:00 +02:00
CVZ-es f33dd84900 Translations: Update Spanish
Currently translated at 100.0% (5869 of 5869 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/es/

powered by weblate
2025-04-30 12:47:00 +02:00
CVZ-es 99d0ca314d Translations: Update French
Currently translated at 100.0% (244 of 244 strings)

Translation: pretix/pretix (JavaScript parts)
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix-js/fr/

powered by weblate
2025-04-30 12:47:00 +02:00
CVZ-es 853749521e Translations: Update French
Currently translated at 100.0% (5869 of 5869 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/fr/

powered by weblate
2025-04-30 12:47:00 +02:00
dependabot[bot] df5c6bcebf Update reportlab requirement from ==4.3.* to ==4.4.* (#5016)
Updates the requirements on [reportlab](https://www.reportlab.com/) to permit the latest version.

---
updated-dependencies:
- dependency-name: reportlab
  dependency-version: 4.4.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-30 11:46:00 +02:00
dependabot[bot] 3e6051825e Update pep8-naming requirement from ==0.14.* to ==0.15.* (#5055)
Updates the requirements on [pep8-naming](https://github.com/PyCQA/pep8-naming) to permit the latest version.
- [Release notes](https://github.com/PyCQA/pep8-naming/releases)
- [Changelog](https://github.com/PyCQA/pep8-naming/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/PyCQA/pep8-naming/compare/0.14.0...0.15.0)

---
updated-dependencies:
- dependency-name: pep8-naming
  dependency-version: 0.15.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-30 11:42:42 +02:00
Richard Schreiber f4478da5ce Fix handling of empty giftcard-code 2025-04-30 07:15:18 +02:00
luelista 013a065132 Fix mismatched headline level in fragment_product_list.html (#5048) 2025-04-29 15:25:15 +02:00
Richard Schreiber b3919973f1 Fix order export for empty attendee_name_parts 2025-04-29 13:35:25 +02:00
Raphael Michel e1027e3e8c OrderChangeManager: Re-use same instances of OrderPosition/OrderFee 2025-04-29 12:38:41 +02:00
Richard Schreiber d3792935ae [A11y] add missing sr-only-text for clock-icon 2025-04-29 12:28:46 +02:00
Davide Manzella 1804dbebd0 Translations: Update Italian
Currently translated at 36.1% (2122 of 5869 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/it/

powered by weblate
2025-04-29 12:00:12 +02:00
Richard Schreiber 7ca2f8ec04 [A11y] add min/max as help_text to date/time inputs
* [A11y] add min/max as help_text to date/time inputs

* update text

* Fix help-text (suggestions from code review)

Co-authored-by: Raphael Michel <michel@rami.io>

---------

Co-authored-by: Raphael Michel <michel@rami.io>
2025-04-29 09:10:29 +02:00
Raphael Michel 15eb0f8870 Bump version to 2025.5.0.dev0 2025-04-28 15:58:04 +02:00
Raphael Michel 01228dd865 Bump version to 2025.4.0 2025-04-28 15:57:22 +02:00
Raphael Michel bbde731dca Translations: Update German (informal) (de_Informal)
Currently translated at 100.0% (244 of 244 strings)

Translation: pretix/pretix (JavaScript parts)
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix-js/de_Informal/

powered by weblate
2025-04-28 14:23:39 +02:00
Raphael Michel b21ea1ba9a Translations: Update German
Currently translated at 100.0% (244 of 244 strings)

Translation: pretix/pretix (JavaScript parts)
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix-js/de/

powered by weblate
2025-04-28 14:23:39 +02:00
Raphael Michel ef1220d240 Translations: Update German (informal) (de_Informal)
Currently translated at 100.0% (5869 of 5869 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/de_Informal/

powered by weblate
2025-04-28 14:23:39 +02:00
Raphael Michel cb3514a14f Translations: Update German
Currently translated at 100.0% (5869 of 5869 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/de/

powered by weblate
2025-04-28 14:23:39 +02:00
Raphael Michel 117a66a837 Update po files
[CI skip]

Signed-off-by: Raphael Michel <michel@rami.io>
2025-04-28 13:08:23 +02:00
Raphael Michel 384d0c4824 Order changes: Correctly respect tax rules when adding or changing items (Z#23190086) 2025-04-28 13:06:45 +02:00
Anarion Dunedain 667443ab56 Translations: Update Polish
Currently translated at 100.0% (236 of 236 strings)

Translation: pretix/pretix (JavaScript parts)
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix-js/pl/

powered by weblate
2025-04-28 12:34:14 +02:00
Anarion Dunedain 22e99cf246 Translations: Update Polish
Currently translated at 99.9% (5862 of 5863 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/pl/

powered by weblate
2025-04-28 12:34:14 +02:00
Anarion Dunedain 3e3cabe2bb Translations: Update Polish
Currently translated at 98.4% (5774 of 5863 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/pl/

powered by weblate
2025-04-28 12:34:14 +02:00
Richard Schreiber ca12cbb69e Fix checkbox-labels always containing text "required" although not being required 2025-04-25 12:17:33 +02:00
Richard Schreiber 21c273854c [A11y] Add sr-only "Log out" to logout-link 2025-04-25 10:31:07 +02:00
Richard Schreiber 0eb11b154b Fix double-thick line between inputs in input-group 2025-04-25 10:30:50 +02:00
Raphael Michel 8796b4359c Add CSS for right-to-left language input fields (#5021) 2025-04-25 09:13:58 +02:00
Richard Schreiber 698f687c54 Fix missing checkbox-button disabled-state 2025-04-23 19:20:46 +02:00
Richard Schreiber ec627d6a3c Fix rem-based input height 2025-04-23 19:20:31 +02:00
Richard Schreiber a252c69988 [A11y] Fix tab order on customer step (remove autofocus on email-field) 2025-04-23 18:07:32 +02:00
Richard Schreiber 578518e8ab [A11y] Fix color contrast on headings-small-color 2025-04-23 18:05:07 +02:00
Raphael Michel d50d6a1dfd Product list: Fix DOM position of label causing wrong border 2025-04-23 17:34:20 +02:00
Richard Schreiber 9d01072880 [A11y] allow users to scale website
* on smaller screens, make fontsize bigger for inputs to not have iPhones zoom on focus
2025-04-23 14:36:28 +02:00
Richard Schreiber 48c2d57cd4 [A11y] fix border contrast for inputs 2025-04-23 14:34:50 +02:00
Paul Berschick 2b245f727e Translations: Update Catalan
Currently translated at 32.5% (1909 of 5863 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/ca/

powered by weblate
2025-04-23 12:41:56 +02:00
Raphael Michel f051ddca2d Translations: Update German (informal) (de_Informal)
Currently translated at 100.0% (5863 of 5863 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/de_Informal/

powered by weblate
2025-04-23 12:41:56 +02:00
Raphael Michel 2ba2f9ff4b Translations: Update German
Currently translated at 100.0% (5863 of 5863 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/de/

powered by weblate
2025-04-23 12:41:56 +02:00
Renne Rocha 4ceb617104 Translations: Update Portuguese (Brazil)
Currently translated at 92.4% (5421 of 5863 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/pt_BR/

powered by weblate
2025-04-23 12:41:56 +02:00
Raphael Michel e1d2721747 Stripe: Do not allow redirect in iframe for PayPal 2025-04-23 12:40:40 +02:00
Richard Schreiber 515f79b206 A11y: do not use px-based fontsizes 2025-04-22 19:47:20 +02:00
Raphael Michel 025ee6710c Fix #4982 -- API: Do not parse decimal input to float (#5012) 2025-04-22 17:36:04 +02:00
Martin Gross 94671f6f70 Docs/Certificates: Fix download-path in API-call sample (Z#23189733) 2025-04-22 10:49:45 +02:00
Raphael Michel c1656158f2 Item categories: Show IDs (required for widget usage) 2025-04-19 20:35:33 +02:00
Raphael Michel d1bd719f66 Translations: Fix inconsistent wording 2025-04-17 13:33:16 +02:00
Raphael Michel d61aed105f Add missing flag config for nb-no 2025-04-17 11:42:06 +02:00
Raphael Michel 4bf4cd748c Fix wrong flag for language code ca 2025-04-17 11:35:05 +02:00
dependabot[bot] 6b58c1484c Update celery requirement from ==5.4.* to ==5.5.* (#5010)
Updates the requirements on [celery](https://github.com/celery/celery) to permit the latest version.
- [Release notes](https://github.com/celery/celery/releases)
- [Changelog](https://github.com/celery/celery/blob/main/Changelog.rst)
- [Commits](https://github.com/celery/celery/compare/v5.4.0rc1...v5.5.1)

---
updated-dependencies:
- dependency-name: celery
  dependency-version: 5.5.1
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-16 22:30:07 +02:00
dependabot[bot] 6cc7a2a0de Bump markdown from 3.7 to 3.8 (#5009)
Bumps [markdown](https://github.com/Python-Markdown/markdown) from 3.7 to 3.8.
- [Release notes](https://github.com/Python-Markdown/markdown/releases)
- [Changelog](https://github.com/Python-Markdown/markdown/blob/master/docs/changelog.md)
- [Commits](https://github.com/Python-Markdown/markdown/compare/3.7...3.8)

---
updated-dependencies:
- dependency-name: markdown
  dependency-version: '3.8'
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-16 22:26:20 +02:00
Raphael Michel c6862454f5 Translations: Update Korean
Currently translated at 18.5% (1087 of 5863 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/ko/

powered by weblate
2025-04-16 22:25:50 +02:00
조정화 6d28a7f384 Translations: Update Korean
Currently translated at 100.0% (236 of 236 strings)

Translation: pretix/pretix (JavaScript parts)
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix-js/ko/

powered by weblate
2025-04-16 22:25:50 +02:00
조정화 15251ff208 Translations: Update Korean
Currently translated at 18.4% (1080 of 5863 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/ko/

powered by weblate
2025-04-16 22:25:50 +02:00
Patrick Chilton fea519962c Translations: Update Hungarian
Currently translated at 10.9% (641 of 5863 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/hu/

powered by weblate
2025-04-16 22:25:50 +02:00
Richard Schreiber 929a2eb6e3 Fix datepicker date display when using min/max (Z#23185544) 2025-04-16 18:12:27 +02:00
dependabot[bot] 08eabfa61c Update sentry-sdk requirement from ==2.24.* to ==2.25.* (#4973)
Updates the requirements on [sentry-sdk](https://github.com/getsentry/sentry-python) to permit the latest version.
- [Release notes](https://github.com/getsentry/sentry-python/releases)
- [Changelog](https://github.com/getsentry/sentry-python/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-python/compare/2.24.0...2.25.0)

---
updated-dependencies:
- dependency-name: sentry-sdk
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-13 18:25:50 +02:00
Raphael Michel 66dfa99e58 Questions: validate that min < max (#4992)
* Questions: validate that min < max

* Update src/pretix/base/models/items.py

Co-authored-by: Richard Schreiber <schreiber@rami.io>

---------

Co-authored-by: Richard Schreiber <schreiber@rami.io>
2025-04-13 18:25:40 +02:00
dependabot[bot] 3b0cd35c7a Update pillow requirement from ==11.1.* to ==11.2.* (#4976)
Updates the requirements on [pillow](https://github.com/python-pillow/Pillow) to permit the latest version.
- [Release notes](https://github.com/python-pillow/Pillow/releases)
- [Changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst)
- [Commits](https://github.com/python-pillow/Pillow/compare/11.1.0...11.2.0)

---
updated-dependencies:
- dependency-name: pillow
  dependency-version: 11.2.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-13 18:25:26 +02:00
dependabot[bot] 810bdff5d9 Update django-otp requirement from ==1.5.* to ==1.6.* (#4996)
Updates the requirements on [django-otp](https://github.com/django-otp/django-otp) to permit the latest version.
- [Changelog](https://github.com/django-otp/django-otp/blob/master/CHANGES.rst)
- [Commits](https://github.com/django-otp/django-otp/compare/v1.5.0...v1.6.0)

---
updated-dependencies:
- dependency-name: django-otp
  dependency-version: 1.6.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-13 18:09:52 +02:00
조정화 54e02da2b3 Translations: Update Korean
Currently translated at 100.0% (236 of 236 strings)

Translation: pretix/pretix (JavaScript parts)
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix-js/ko/

powered by weblate
2025-04-13 18:09:30 +02:00
조정화 86133ee52f Translations: Update Korean
Currently translated at 15.0% (883 of 5863 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/ko/

powered by weblate
2025-04-13 18:09:30 +02:00
Menaouer Chaabi 1e3b924998 Translations: Update Arabic
Currently translated at 63.3% (3712 of 5863 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/ar/

powered by weblate
2025-04-13 18:09:30 +02:00
Menaouer Chaabi ac2b1186d1 Translations: Update Arabic
Currently translated at 63.2% (3711 of 5863 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/ar/

powered by weblate
2025-04-13 18:09:30 +02:00
dependabot[bot] 9608c7aa15 Bump qrcode from 8.0 to 8.1 (#5003)
Bumps [qrcode](https://github.com/lincolnloop/python-qrcode) from 8.0 to 8.1.
- [Changelog](https://github.com/lincolnloop/python-qrcode/blob/main/CHANGES.rst)
- [Commits](https://github.com/lincolnloop/python-qrcode/commits)

---
updated-dependencies:
- dependency-name: qrcode
  dependency-version: '8.1'
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-13 18:06:13 +02:00
Richard Schreiber 2bb324f885 Fix datepicker locale when using min/max 2025-04-09 14:38:27 +02:00
Richard Schreiber ea955c779e Fix image size in help-text for logo-images 2025-04-08 20:40:18 +02:00
Raphael Michel 9844ffca98 Discounts: Fix incorrect test for subevent date limitation (#4991)
If two discounts match the same products, the first one wins. Therefore,
the one we want to win in the test must always come last, otherwise the
test is not actually testing anything. In this case, this is highlighted
by the fact that the test does not pass in diffrent orders of discounts
unless we subtract a second from the date, because we compare with <=,
not <.
2025-04-07 17:37:55 +02:00
Richard Schreiber 12f4473fbd Fix checkin-list-filter test randomly matching secret 2025-04-07 15:31:07 +02:00
luelista 8c3ac46ddf Fix bug in Question.clean_answer (#4987) 2025-04-07 15:19:54 +02:00
Raphael Michel b4d8e9ccc4 Backend event list: Sort event series by their actual dates, like in the frontend (Z#23187301) (#4993) 2025-04-07 14:34:32 +02:00
luelista 899994ef1e Improve SOLD OUT / FULLY BOOKED message logic (Z#23187802) (#4988)
Show SOLD OUT instead of FULLY BOOKED if ticket is not free of charge even if a voucher gives 100% off
2025-04-07 13:51:59 +02:00
luelista 277a5bffa8 Allow changing ticket secret via API (Z#23188201) (#4989) 2025-04-07 13:49:19 +02:00
dependabot[bot] 1bbefddc11 Update flake8 requirement from ==7.1.* to ==7.2.* (#4972)
* Update flake8 requirement from ==7.1.* to ==7.2.*

Updates the requirements on [flake8](https://github.com/pycqa/flake8) to permit the latest version.
- [Commits](https://github.com/pycqa/flake8/compare/7.1.0...7.2.0)

---
updated-dependencies:
- dependency-name: flake8
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

* Resolve warning

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Raphael Michel <michel@rami.io>
2025-04-06 09:23:56 +02:00
dependabot[bot] 957462739a Bump @babel/core from 7.26.9 to 7.26.10 in /src/pretix/static/npm_dir (#4975)
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.26.9 to 7.26.10.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.26.10/packages/babel-core)

---
updated-dependencies:
- dependency-name: "@babel/core"
  dependency-version: 7.26.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-06 09:19:47 +02:00
dependabot[bot] fa468366c7 Bump @rollup/plugin-node-resolve in /src/pretix/static/npm_dir (#4974)
Bumps [@rollup/plugin-node-resolve](https://github.com/rollup/plugins/tree/HEAD/packages/node-resolve) from 16.0.0 to 16.0.1.
- [Changelog](https://github.com/rollup/plugins/blob/master/packages/node-resolve/CHANGELOG.md)
- [Commits](https://github.com/rollup/plugins/commits/node-resolve-v16.0.1/packages/node-resolve)

---
updated-dependencies:
- dependency-name: "@rollup/plugin-node-resolve"
  dependency-version: 16.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-06 09:19:39 +02:00
Loïc Alejandro 9a61de9a22 Translations: Update French
Currently translated at 100.0% (5863 of 5863 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/fr/

powered by weblate
2025-04-04 11:20:58 +02:00
조정화 17df83a9fb Translations: Update Korean
Currently translated at 13.7% (805 of 5863 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/ko/

powered by weblate
2025-04-04 11:20:58 +02:00
Fernando Luiz f3bd918846 Translations: Update Portuguese (Brazil)
Currently translated at 92.1% (5401 of 5863 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/pt_BR/

powered by weblate
2025-04-04 11:20:58 +02:00
Hijiri Umemoto 5768fbca54 Translations: Update Japanese
Currently translated at 100.0% (236 of 236 strings)

Translation: pretix/pretix (JavaScript parts)
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix-js/ja/

powered by weblate
2025-04-04 11:20:58 +02:00
Hijiri Umemoto d88e47d76b Translations: Update Japanese
Currently translated at 100.0% (5863 of 5863 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/ja/

powered by weblate
2025-04-04 11:20:58 +02:00
luelista d8ec489b13 OrderChangeManager: Fix for change_tax_rule and recalculate_taxes in same transaction (Z#23187299) (#4964)
* Add test case

* Do not overwrite tax_rule in PriceOperation
2025-03-31 12:27:45 +02:00
Raphael Michel 804b048dbb Check-in API: Return order locale, and allow to use order locale for … (#4969)
* Check-in API: Return order locale, and allow to use order locale for reasons

* Fix failing tests
2025-03-31 12:26:46 +02:00
Renne Rocha a3d721c08b Add Federal district (DF) to state dropdown for Brazil (BR) (#4966) 2025-03-31 12:15:17 +02:00
dependabot[bot] b5544b120d Update djangorestframework requirement from ==3.15.* to ==3.16.* (#4965)
Updates the requirements on [djangorestframework](https://github.com/encode/django-rest-framework) to permit the latest version.
- [Release notes](https://github.com/encode/django-rest-framework/releases)
- [Commits](https://github.com/encode/django-rest-framework/compare/3.15.0...3.16.0)

---
updated-dependencies:
- dependency-name: djangorestframework
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-31 12:14:53 +02:00
Raphael Michel 5138e86cf1 Order search: Keep searching in canceled positions (Z#23187097) (#4963) 2025-03-31 12:14:00 +02:00
luelista f455152447 Show link to stripe payment receipt in backend (Z#23187178) (#4961)
* Show link to stripe payment receipt in backend (Z#23187178)

* Revert "Show link to stripe payment receipt in backend (Z#23187178)"

This reverts commit 4a261ac1ac.

* Show link to stripe payment receipt in backend payment details (Z#23187178)
2025-03-31 12:13:04 +02:00
Richard Schreiber 9447e5802d PDF-Editor: improve UI for page-size and background PDF (#4959)
* PDF-Editor: improve UI for page-size and background PDF

* Update src/pretix/control/templates/pretixcontrol/pdf/index.html

Co-authored-by: leiascyr <156191181+leiascyr@users.noreply.github.com>

* Update src/pretix/control/templates/pretixcontrol/pdf/index.html

Co-authored-by: leiascyr <156191181+leiascyr@users.noreply.github.com>

* Update label text

Co-authored-by: Raphael Michel <michel@rami.io>

---------

Co-authored-by: Raphael Michel <michel@rami.io>
Co-authored-by: leiascyr <156191181+leiascyr@users.noreply.github.com>
2025-03-31 12:11:49 +02:00
Jan Van Haver e5fc7144e4 Translations: Update Dutch
Currently translated at 77.5% (183 of 236 strings)

Translation: pretix/pretix (JavaScript parts)
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix-js/nl/

powered by weblate
2025-03-31 12:09:05 +02:00
Jan Van Haver a7c8bb0f02 Translations: Update Dutch
Currently translated at 99.8% (5853 of 5863 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/nl/

powered by weblate
2025-03-31 12:09:05 +02:00
Jan Van Haver fbb6246020 Translations: Update Dutch
Currently translated at 99.5% (5836 of 5863 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/nl/

powered by weblate
2025-03-31 12:09:05 +02:00
luelista d39a01af4d Fix bulk edit of revoked devices (Z#23187227) (#4960)
When selecting revoked devices and using bulk edit on them, the edit was performed 
either *on all active devices* or not at all. This commit fixes that behaviour so that the 
selected devices are edited.
2025-03-28 17:59:55 +01:00
Raphael Michel d928adf7a3 Sort organizers in typeahead by number of events (Z##23185900) (#4912) 2025-03-27 17:28:10 +01:00
luelista 4755200ab0 order_overview: allow filtering by time (#4958) 2025-03-27 17:23:08 +01:00
Phin Wolkwitz 0b8a7349c7 Discounts: Add applicability date ranges (Z#23151897) (#4927)
* Add event date fields, add preliminary range check

* Remove function, use filtered queryset for subevent id limit

* Improve and fix date range check

* Add formfields

* Add tests

* Improve tests

* Add new fields to API and documentation

* Add migration

* Change description according to suggestion

* Change discount apply signature, remove unnecessary query

* Rename new fields, simplify range check

* Rename fields in template

* Apply suggestions from code review

Co-authored-by: Raphael Michel <michel@rami.io>

---------

Co-authored-by: Raphael Michel <michel@rami.io>
2025-03-27 15:36:20 +01:00
Richard Schreiber 1a1948e3fa [A11y] Improve HTML-output for date-ranges 2025-03-27 13:21:25 +01:00
Richard Schreiber f70874b21c [A11y] Widget: add missing labels to dialog and iframe 2025-03-27 13:20:13 +01:00
Richard Schreiber 1c8bcca846 [A11y] Improve focus management for widget overlay 2025-03-27 13:18:59 +01:00
Raphael Michel 6c7041c875 Add a label for empty salutation option (Z#23183319) (#4913) 2025-03-27 12:09:04 +01:00
CVZ-es 8c9a94f87e Translations: Update Spanish
Currently translated at 100.0% (236 of 236 strings)

Translation: pretix/pretix (JavaScript parts)
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix-js/es/

powered by weblate
2025-03-27 11:05:45 +01:00
CVZ-es 6f3c2ed444 Translations: Update Spanish
Currently translated at 100.0% (5863 of 5863 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/es/

powered by weblate
2025-03-27 11:05:45 +01:00
CVZ-es 736792fc01 Translations: Update French
Currently translated at 100.0% (236 of 236 strings)

Translation: pretix/pretix (JavaScript parts)
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix-js/fr/

powered by weblate
2025-03-27 11:05:45 +01:00
CVZ-es bacb40fd7f Translations: Update French
Currently translated at 100.0% (5863 of 5863 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/fr/

powered by weblate
2025-03-27 11:05:45 +01:00
Raphael Michel 42399c3488 Date picker: Guess default time 23:59 for end dates (Z#23182900) (#4917)
* Date picker: Guess default time 23:59 for end dates (Z#23182900)

* Update src/pretix/static/pretixcontrol/js/ui/main.js

Co-authored-by: luelista <weller@rami.io>

* Update src/pretix/static/pretixpresale/js/ui/main.js

Co-authored-by: luelista <weller@rami.io>

---------

Co-authored-by: luelista <weller@rami.io>
2025-03-27 11:04:02 +01:00
Raphael Michel 592b98b83a Bump version to 2025.4.0.dev0 2025-03-26 16:08:03 +01:00
Raphael Michel 83c333c798 Bump version to 2025.3.0 2025-03-26 16:07:39 +01:00
Raphael Michel ff76fe38e3 Do not show ticket attachments as information is not reliable (refs #4945) 2025-03-26 15:57:27 +01:00
dependabot[bot] 8dff640d54 Update sentry-sdk requirement from ==2.23.* to ==2.24.* (#4952)
Updates the requirements on [sentry-sdk](https://github.com/getsentry/sentry-python) to permit the latest version.
- [Release notes](https://github.com/getsentry/sentry-python/releases)
- [Changelog](https://github.com/getsentry/sentry-python/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-python/compare/2.23.0...2.24.1)

---
updated-dependencies:
- dependency-name: sentry-sdk
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-26 15:42:58 +01:00
dependabot[bot] 339820a5a0 Update kombu requirement from ==5.4.* to ==5.5.* (#4951)
Updates the requirements on [kombu](https://github.com/celery/kombu) to permit the latest version.
- [Release notes](https://github.com/celery/kombu/releases)
- [Changelog](https://github.com/celery/kombu/blob/main/Changelog.rst)
- [Commits](https://github.com/celery/kombu/compare/v5.4.0rc1...v5.5.1)

---
updated-dependencies:
- dependency-name: kombu
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-26 15:42:46 +01:00
Raphael Michel 47990dc1d6 Translations: Update German (informal) (de_Informal)
Currently translated at 100.0% (236 of 236 strings)

Translation: pretix/pretix (JavaScript parts)
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix-js/de_Informal/

powered by weblate
2025-03-26 14:58:30 +01:00
Raphael Michel 4db9b719ed Translations: Update German
Currently translated at 100.0% (236 of 236 strings)

Translation: pretix/pretix (JavaScript parts)
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix-js/de/

powered by weblate
2025-03-26 14:58:30 +01:00
Raphael Michel 873a2d02df Translations: Update German (informal) (de_Informal)
Currently translated at 100.0% (5863 of 5863 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/de_Informal/

powered by weblate
2025-03-26 14:58:30 +01:00
Raphael Michel 8ab94bb294 Translations: Update German
Currently translated at 100.0% (5863 of 5863 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/de/

powered by weblate
2025-03-26 14:58:30 +01:00
Richard Schreiber a903cfa4d1 API: fix event creation sales-channel-migration (#4949)
* API: fix event creation sales-channel-migration

* do not allow sales_channels to be None

* fix wrong validation error-key
2025-03-25 16:52:29 +01:00
Kian Cross 06efb37d5d Clarify description for offsetting refunds (#4943)
The 'offsetting' payment method includes a clear description specifying
which order the offsetting applies to, but the associated refund does
not. This commit ensures refunds use the same message as payments,
making the associated order explicit.
2025-03-25 16:52:04 +01:00
Raphael Michel 533698c33f Update po files
[CI skip]

Signed-off-by: Raphael Michel <michel@rami.io>
2025-03-25 16:46:43 +01:00
dependabot[bot] d7d946878c Update phonenumberslite requirement from ==8.13.* to ==9.0.* (#4888)
Updates the requirements on [phonenumberslite](https://github.com/daviddrysdale/python-phonenumbers) to permit the latest version.
- [Commits](https://github.com/daviddrysdale/python-phonenumbers/compare/v8.13.0...v9.0.0)

---
updated-dependencies:
- dependency-name: phonenumberslite
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-25 12:09:57 +01:00
dependabot[bot] 633ff804a8 Update pycryptodome requirement from ==3.21.* to ==3.22.* (#4939)
Updates the requirements on [pycryptodome](https://github.com/Legrandin/pycryptodome) to permit the latest version.
- [Release notes](https://github.com/Legrandin/pycryptodome/releases)
- [Changelog](https://github.com/Legrandin/pycryptodome/blob/master/Changelog.rst)
- [Commits](https://github.com/Legrandin/pycryptodome/compare/v3.21.0...v3.22.0)

---
updated-dependencies:
- dependency-name: pycryptodome
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-25 11:24:49 +01:00
dependabot[bot] e5997d3a14 Update protobuf requirement from ==5.29.* to ==6.30.* (#4938)
Updates the requirements on [protobuf](https://github.com/protocolbuffers/protobuf) to permit the latest version.
- [Release notes](https://github.com/protocolbuffers/protobuf/releases)
- [Changelog](https://github.com/protocolbuffers/protobuf/blob/main/protobuf_release.bzl)
- [Commits](https://github.com/protocolbuffers/protobuf/compare/v5.29.0-rc1...v6.30.1)

---
updated-dependencies:
- dependency-name: protobuf
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-25 11:23:17 +01:00
dependabot[bot] d1faee0b8f Update pypdf requirement from ==5.1.* to ==5.4.*
Updates the requirements on [pypdf](https://github.com/py-pdf/pypdf) to permit the latest version.
- [Release notes](https://github.com/py-pdf/pypdf/releases)
- [Changelog](https://github.com/py-pdf/pypdf/blob/main/CHANGELOG.md)
- [Commits](https://github.com/py-pdf/pypdf/compare/5.1.0...5.4.0)

---
updated-dependencies:
- dependency-name: pypdf
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-25 11:22:46 +01:00
Raphael Michel 41e8ab7717 Translations: Update German (informal) (de_Informal)
Currently translated at 100.0% (5853 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/de_Informal/

powered by weblate
2025-03-24 18:11:17 +01:00
Renne Rocha 3a3f45a988 Translations: Update Portuguese (Brazil)
Currently translated at 91.5% (5357 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/pt_BR/

powered by weblate
2025-03-24 18:11:17 +01:00
Dennis Lichtenthäler b4ead8f814 Translations: Update German
Currently translated at 100.0% (5853 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/de/

powered by weblate
2025-03-24 18:11:17 +01:00
조정화 19cf34b42d Translations: Update Korean
Currently translated at 9.5% (561 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/ko/

powered by weblate
2025-03-24 18:11:17 +01:00
Raphael Michel 8ec8b69755 PayPal: Prevent race condition between refund and incoming webhook (Z#23185186) (#4911) 2025-03-24 18:10:58 +01:00
Richard Schreiber de9a86c614 Fix label matching when copying answers (#4946) 2025-03-24 17:25:33 +01:00
luelista 5375e22781 Add search and links to plugin settings (#4854)
* Show links to plugin views and settings in plugin list and in success message after activating a plugin
* Fix menu highlighting in payment provider settings
* Specify settings_links and navigation_links for built-in plugins
* Add link to payment plugins from payment settings
* Add client-side search and "View only active plugins" for plugins page
2025-03-24 15:04:35 +01:00
luelista 6a92b98766 Event order list: Search in attendee company field (Z#23186263) (#4941) 2025-03-24 15:04:17 +01:00
Mira 999055f082 Refactor copy_to_first_ticket, fixes issue #4860 (#4865)
---------

Co-authored-by: Richard Schreiber <schreiber@rami.io>
2025-03-20 15:48:11 +01:00
Raphael Michel b969f114f5 PDF editor: Allow Alt+Arrow for small adjustments (Z#23186382) (#4936)
* PDF editor: Allow Alt+Arrow for small adjustments (Z#23186382)

* Update src/pretix/static/pretixcontrol/js/ui/editor.js

Co-authored-by: Richard Schreiber <schreiber@rami.io>

---------

Co-authored-by: Richard Schreiber <schreiber@rami.io>
2025-03-19 16:47:18 +01:00
Mira 695e817f99 Fix Exception when displaying mail_history (PRETIXEU-BB0) (#4934)
* Fix Exception when displaying mail_history

Log entries of type pretix.plugins.banktransfer.order.email.invoice had type(invoices) == int instead of list

* Update src/pretix/control/views/orders.py

Co-authored-by: Richard Schreiber <schreiber@rami.io>

---------

Co-authored-by: Raphael Michel <michel@rami.io>
Co-authored-by: Richard Schreiber <schreiber@rami.io>
2025-03-19 14:10:41 +01:00
Mira b7caf7769e Don't ignore free price input in the cross-selling step in an event series (issue #4850) (#4933) 2025-03-19 10:26:37 +01:00
Raphael Michel 67b65bf67d SMTP config: Do not accept non-ASCII passwords (Z#23186129) (#4922)
* SMTP config: Do not accept non-ASCII passwords

Python's SMTP implementation can't seem to handle non-ascii passwords,
so let's not let people enter them.

* Update src/pretix/control/forms/mailsetup.py

Co-authored-by: Mira <weller@rami.io>

---------

Co-authored-by: Mira <weller@rami.io>
2025-03-19 10:25:19 +01:00
Mira 9ca0e41c5f Do not match failed offline checkins to order positions from another event (Z#23181592) (#4932) 2025-03-19 09:49:51 +01:00
Hector d562a2858d Translations: Update Spanish
Currently translated at 100.0% (5853 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/es/

powered by weblate
2025-03-19 09:24:04 +01:00
Rosariocastellana 728c6d30a3 Translations: Update Italian
Currently translated at 36.2% (2119 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/it/

powered by weblate
2025-03-19 09:24:04 +01:00
Renne Rocha 1bbbfb5cf9 Translations: Update Portuguese (Brazil)
Currently translated at 91.4% (5354 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/pt_BR/

powered by weblate
2025-03-19 09:24:04 +01:00
Renne Rocha c9dd65fba8 Translations: Update Portuguese (Brazil)
Currently translated at 91.4% (5354 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/pt_BR/

powered by weblate
2025-03-19 09:24:04 +01:00
Renne Rocha f5989cb2ff Translations: Update Portuguese (Brazil)
Currently translated at 89.7% (5253 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/pt_BR/

powered by weblate
2025-03-19 09:24:04 +01:00
Hijiri Umemoto a27af1373b Translations: Update Japanese
Currently translated at 100.0% (5853 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/ja/

powered by weblate
2025-03-19 09:24:04 +01:00
CVZ-es 5e2633efa8 Translations: Update Spanish
Currently translated at 100.0% (5853 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/es/

powered by weblate
2025-03-19 09:24:04 +01:00
Renne Rocha 0144c6341e Translations: Update Portuguese (Brazil)
Currently translated at 88.0% (5152 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/pt_BR/

powered by weblate
2025-03-19 09:24:04 +01:00
CVZ-es 9a57aa67b2 Translations: Update French
Currently translated at 100.0% (5853 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/fr/

powered by weblate
2025-03-19 09:24:04 +01:00
Raphael Michel 7652f48dc1 New consistent representation of date ranges with times (Z#23184657) 2025-03-18 14:40:38 +01:00
dependabot[bot] a22cc56944 Bump @babel/runtime from 7.26.0 to 7.26.10 in /src/pretix/static/npm_dir
Bumps [@babel/runtime](https://github.com/babel/babel/tree/HEAD/packages/babel-runtime) from 7.26.0 to 7.26.10.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.26.10/packages/babel-runtime)

---
updated-dependencies:
- dependency-name: "@babel/runtime"
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-18 14:38:32 +01:00
dependabot[bot] 322329d956 Bump @babel/helpers from 7.26.9 to 7.26.10 in /src/pretix/static/npm_dir
Bumps [@babel/helpers](https://github.com/babel/babel/tree/HEAD/packages/babel-helpers) from 7.26.9 to 7.26.10.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.26.10/packages/babel-helpers)

---
updated-dependencies:
- dependency-name: "@babel/helpers"
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-18 14:38:22 +01:00
Mira 2186a17530 Pass widget_data to new tab even if 3rd-party cookies are disabled (Z#23176995) (#4899)
* Pass widget_data to new tab even if 3rd-party cookies are disabled (Z#23176995)

* Perform cookie check earlier

* Deduplicate redirect code

* Don't forget the subevent id

* We still need to pass thru the widget_data parameter
because for an empty cart, take_cart_id will do nothing.

* pass through "consent" as GET-param as well

---------

Co-authored-by: Richard Schreiber <schreiber@rami.io>
2025-03-18 14:25:29 +01:00
dependabot[bot] 3b632728e3 Update sentry-sdk requirement from ==2.22.* to ==2.23.* (#4924)
Updates the requirements on [sentry-sdk](https://github.com/getsentry/sentry-python) to permit the latest version.
- [Release notes](https://github.com/getsentry/sentry-python/releases)
- [Changelog](https://github.com/getsentry/sentry-python/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-python/compare/2.22.0...2.23.1)

---
updated-dependencies:
- dependency-name: sentry-sdk
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-18 14:24:43 +01:00
Mira addba1ff57 Display "Order status" correctly in the "Search query" line of advanced search results (#4926) 2025-03-18 14:24:24 +01:00
Raphael Michel 4740291e43 Event list: Move empty message inside panel (Z#23185800) (#4910)
* Event list: Move empty message inside panel (Z#23185800)

* Review notes and adjust some margins
2025-03-18 14:22:34 +01:00
Raphael Michel 745929b625 Order email: Allow to attach default attachment (Z#23185463, #4903) (#4915) 2025-03-18 13:52:50 +01:00
Richard Schreiber 7da03ac17c Fix concurrent login and duplicate UserKnownLoginSources (#4880) 2025-03-18 10:24:15 +01:00
Raphael Michel ac8cb3bfd1 Order search: Fix typing errors in advanced search (fixes #4900) (#4919) 2025-03-18 09:01:30 +01:00
Raphael Michel 0236911a88 Order search: Proper input validation with error feedback for advanced search (#4920) 2025-03-18 09:01:13 +01:00
Raphael Michel f475781a89 Order email history: Record more information about attachments (Z#23185463) (#4914) 2025-03-18 08:58:54 +01:00
Raphael Michel fcd8c82092 Fix context processor crash on "event not found" page (PRETIXEU-BAS) (#4918) 2025-03-18 08:58:40 +01:00
Richard Schreiber 9ec9c67550 Fix API cartpositions without answers (#4909) 2025-03-17 13:05:46 +01:00
Richard Schreiber 3eff74bf4c Refactor widget redeeming voucher form (#4890) 2025-03-17 11:38:59 +01:00
Raphael Michel d0d17a1d0a Order: Use different icon for non-consuming check-in list (Z#23184645) (#4916) 2025-03-17 11:25:48 +01:00
Raphael Michel 0cca053d45 Address form: Add provinces for Italy 2025-03-17 10:36:29 +01:00
Raphael Michel 9581457d2f Fix typo on 400 error page (fixes #4897) 2025-03-17 09:44:21 +01:00
Luca Martinelli [Sannita] 7475a5d7b1 Translations: Update Italian
Currently translated at 74.8% (176 of 235 strings)

Translation: pretix/pretix (JavaScript parts)
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix-js/it/

powered by weblate
2025-03-17 09:39:46 +01:00
Luca Martinelli [Sannita] e211f006e3 Translations: Update Italian
Currently translated at 36.1% (2118 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/it/

powered by weblate
2025-03-17 09:39:46 +01:00
Robert Rigo 924aa3ac51 Translations: Update Croatian
Currently translated at 5.9% (14 of 235 strings)

Translation: pretix/pretix (JavaScript parts)
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix-js/hr/

powered by weblate
2025-03-17 09:39:46 +01:00
Luca Martinelli [Sannita] 6bfd61b789 Translations: Update Italian
Currently translated at 32.3% (1894 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/it/

powered by weblate
2025-03-17 09:39:46 +01:00
Kristian Feldsam 6c71fa8c5a Translations: Update Slovak
Currently translated at 90.0% (5269 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/sk/

powered by weblate
2025-03-17 09:39:46 +01:00
Luca Martinelli [Sannita] 945f5e9dcb Translations: Update Italian
Currently translated at 31.1% (1823 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/it/

powered by weblate
2025-03-17 09:39:46 +01:00
Luca Martinelli [Sannita] 7c18d46760 Translations: Update Italian
Currently translated at 74.8% (176 of 235 strings)

Translation: pretix/pretix (JavaScript parts)
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix-js/it/

powered by weblate
2025-03-17 09:39:46 +01:00
Rosariocastellana 52020bc866 Translations: Update Italian
Currently translated at 29.4% (1726 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/it/

powered by weblate
2025-03-17 09:39:46 +01:00
Luca Martinelli [Sannita] 2cec516ad7 Translations: Update Italian
Currently translated at 29.4% (1726 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/it/

powered by weblate
2025-03-17 09:39:46 +01:00
Luca Martinelli [Sannita] 44aad7834c Translations: Update Italian
Currently translated at 26.5% (1554 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/it/

powered by weblate
2025-03-17 09:39:46 +01:00
Renne Rocha 92ebcddbbb Translations: Update Portuguese (Brazil)
Currently translated at 86.6% (5073 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/pt_BR/

powered by weblate
2025-03-17 09:39:46 +01:00
Luca Martinelli [Sannita] d2f694b260 Translations: Update Italian
Currently translated at 25.6% (1504 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/it/

powered by weblate
2025-03-17 09:39:46 +01:00
Rosariocastellana ea3b557fcc Translations: Update Italian
Currently translated at 25.6% (1501 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/it/

powered by weblate
2025-03-17 09:39:46 +01:00
Luca Martinelli [Sannita] 8ea03b54a3 Translations: Update Italian
Currently translated at 25.6% (1501 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/it/

powered by weblate
2025-03-17 09:39:46 +01:00
Luca Martinelli [Sannita] 6dae8ef6b7 Translations: Update Italian
Currently translated at 24.6% (1442 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/it/

powered by weblate
2025-03-17 09:39:46 +01:00
Davide Manzella 502ebcbc27 Translations: Update Italian
Currently translated at 24.6% (1442 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/it/

powered by weblate
2025-03-17 09:39:46 +01:00
M C 19a2f7b0d3 Translations: Update Italian
Currently translated at 24.6% (1443 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/it/

powered by weblate
2025-03-17 09:39:46 +01:00
Luca Martinelli [Sannita] 7c9a0343e5 Translations: Update Italian
Currently translated at 24.6% (1443 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/it/

powered by weblate
2025-03-17 09:39:46 +01:00
Luca Martinelli [Sannita] f006b765f2 Translations: Update Italian
Currently translated at 24.6% (1443 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/it/

powered by weblate
2025-03-17 09:39:46 +01:00
Rosariocastellana de71754d9f Translations: Update Italian
Currently translated at 24.6% (1443 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/it/

powered by weblate
2025-03-17 09:39:46 +01:00
Rosariocastellana 844547d356 Translations: Update Italian
Currently translated at 24.6% (1443 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/it/

powered by weblate
2025-03-17 09:39:46 +01:00
Luca Martinelli [Sannita] afb939c622 Translations: Update Italian
Currently translated at 24.6% (1443 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/it/

powered by weblate
2025-03-17 09:39:46 +01:00
Renne Rocha ccefca5d0c Translations: Update Portuguese (Brazil)
Currently translated at 86.6% (5073 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/pt_BR/

powered by weblate
2025-03-17 09:39:46 +01:00
Hector a2252fb021 Translations: Update Spanish
Currently translated at 100.0% (5853 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/es/

powered by weblate
2025-03-17 09:39:46 +01:00
Renne Rocha 16b7e28074 Translations: Update Portuguese (Brazil)
Currently translated at 84.9% (4973 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/pt_BR/

powered by weblate
2025-03-17 09:39:46 +01:00
Wiktor Przybylski e0957639ad Translations: Update Polish
Currently translated at 98.4% (5762 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/pl/

powered by weblate
2025-03-17 09:39:46 +01:00
조정화 392e31837e Translations: Update Korean
Currently translated at 7.1% (418 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/ko/

powered by weblate
2025-03-17 09:39:46 +01:00
Renne Rocha 51271463fb Translations: Update Portuguese (Brazil)
Currently translated at 82.9% (4854 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/pt_BR/

powered by weblate
2025-03-17 09:39:46 +01:00
Renne Rocha 80e289f67e Translations: Update Portuguese (Brazil)
Currently translated at 79.9% (4679 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/pt_BR/

powered by weblate
2025-03-17 09:39:46 +01:00
MaartenUreel 79d420fa9b Translations: Update Dutch
Currently translated at 98.6% (5775 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/nl/

powered by weblate
2025-03-17 09:39:46 +01:00
Renne Rocha e6ac66ff19 Translations: Update Portuguese (Brazil)
Currently translated at 79.8% (4671 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/pt_BR/

powered by weblate
2025-03-17 09:39:46 +01:00
Mikkel Ricky 495aaa762c Translations: Update Danish
Currently translated at 48.1% (2816 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/da/

powered by weblate
2025-03-17 09:39:46 +01:00
Renne Rocha 43d967fe60 Translations: Update Portuguese (Brazil)
Currently translated at 79.5% (4655 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/pt_BR/

powered by weblate
2025-03-17 09:39:46 +01:00
MaartenUreel 8a9060da7c Translations: Update Dutch
Currently translated at 98.5% (5769 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/nl/

powered by weblate
2025-03-17 09:39:46 +01:00
Samuel Bramming fc4b46a140 Translations: Update Danish
Currently translated at 48.0% (2813 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/da/

powered by weblate
2025-03-17 09:39:46 +01:00
Renne Rocha 0c27ac5d27 Translations: Update Portuguese (Brazil)
Currently translated at 76.0% (4453 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/pt_BR/

powered by weblate
2025-03-17 09:39:46 +01:00
Raphael Michel 12da2666db PDF: Update label of layout editor (nowhere else called designer) 2025-03-16 10:40:47 +01:00
Raphael Michel 03bdfe3540 Base payment provider: Reorder fields 2025-03-16 10:40:47 +01:00
Raphael Michel 8bce847054 PDF editor: Set company for sample attendee 2025-03-16 10:40:47 +01:00
Raphael Michel c8cdf0438f Fix a typo 2025-03-16 10:40:47 +01:00
Raphael Michel 42b432daa2 Update .clabot 2025-03-14 17:08:38 +01:00
Renne Rocha 88bc144028 Add missing question mark to delete check-ins confirmation form (#4908)
It is a question, so it needs to end with a question mark.
2025-03-14 17:07:32 +01:00
Richard Schreiber 032be74d77 Add min/max-limit on giftcard_expiry_years 2025-03-12 08:54:40 +01:00
Raphael Michel e2e811ea47 Search engines: Do not index event lists for specific dates (#23185037) (#4901) 2025-03-11 16:09:40 +01:00
Renne Rocha febf32a0a4 Translations: Update Portuguese (Brazil)
Currently translated at 74.4% (4358 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/pt_BR/

powered by weblate
2025-03-07 14:46:39 +01:00
Renne Rocha 0a63ae67d3 Translations: Update Portuguese (Brazil)
Currently translated at 74.4% (4358 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/pt_BR/

powered by weblate
2025-03-07 14:46:39 +01:00
Renne Rocha da4438bbf7 Translations: Update Portuguese (Brazil)
Currently translated at 69.9% (4094 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/pt_BR/

powered by weblate
2025-03-07 14:46:39 +01:00
조정화 6dc5f5bc99 Translations: Update Korean
Currently translated at 2.2% (133 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/ko/

powered by weblate
2025-03-07 14:46:39 +01:00
Renne Rocha a6d3139e25 Translations: Update Portuguese (Brazil)
Currently translated at 69.2% (4053 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/pt_BR/

powered by weblate
2025-03-07 14:46:39 +01:00
조정화 7348c1a3d4 Translations: Update Korean
Currently translated at 2.1% (127 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/ko/

powered by weblate
2025-03-07 14:46:39 +01:00
Renne Rocha 16811a1e63 Translations: Update Portuguese (Brazil)
Currently translated at 67.5% (3953 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/pt_BR/

powered by weblate
2025-03-07 14:46:39 +01:00
Martin Gross de3fd54a27 ical: Remove Markdown indicator for mail_attach_ical_description (Z#23184634) 2025-03-06 12:31:35 +01:00
dependabot[bot] 201def6aae Bump @babel/preset-env in /src/pretix/static/npm_dir (#4884)
Bumps [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env) from 7.26.7 to 7.26.9.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.26.9/packages/babel-preset-env)

---
updated-dependencies:
- dependency-name: "@babel/preset-env"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-04 18:43:37 +01:00
Raphael Michel e38ff7021d Widget: Fix missing consent parameters 2025-03-04 18:25:58 +01:00
Raphael Michel b9c94f21af Checkin list CSV export: Use stable orderings (#4866) 2025-03-04 17:27:42 +01:00
pretix translation bot 6d9edea05e Update translations (#4887)
* Translations: Update Portuguese (Brazil)

Currently translated at 64.1% (3757 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/pt_BR/

powered by weblate

* Translations: Update Croatian

Currently translated at 5.1% (12 of 235 strings)

Translation: pretix/pretix (JavaScript parts)
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix-js/hr/

powered by weblate

* Translations: Update Portuguese (Brazil)

Currently translated at 65.8% (3853 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/pt_BR/

powered by weblate

* Translations: Update Croatian

Currently translated at 84.4% (4943 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/hr/

powered by weblate

* Translations: Update Croatian

Currently translated at 84.4% (4943 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/hr/

powered by weblate

* Translations: Update Croatian

Currently translated at 5.5% (13 of 235 strings)

Translation: pretix/pretix (JavaScript parts)
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix-js/hr/

powered by weblate

---------

Co-authored-by: Renne Rocha <renne@rocha.dev.br>
Co-authored-by: Robert Rigo <kontakt@bicikli.hr>
Co-authored-by: Raphael Michel <michel@rami.io>
Co-authored-by: Martin Gross <gross@rami.io>
2025-03-04 17:17:46 +01:00
Raphael Michel d9e8dd70e4 New mechanism to transfer cookie consent from the widget (Z#23181715) (#4875)
* Cookie consent: Add separate storage layer for widget

* Widget: Move cookie consent out of widget_data

* Add consent parameter to forms
2025-03-04 15:28:03 +01:00
Wiktor Przybylski 0e17ac6ea5 Translations: Update Polish
Currently translated at 100.0% (235 of 235 strings)

Translation: pretix/pretix (JavaScript parts)
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix-js/pl/

powered by weblate
2025-03-03 17:19:32 +01:00
Wiktor Przybylski 1bdec48552 Translations: Update Polish
Currently translated at 98.4% (5762 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/pl/

powered by weblate
2025-03-03 17:19:32 +01:00
Renne Rocha a7e92657b0 Translations: Update Portuguese (Brazil)
Currently translated at 57.2% (3353 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/pt_BR/

powered by weblate
2025-03-03 17:19:32 +01:00
dependabot[bot] 5bf9980e8a Bump django-bootstrap3 from 24.3 to 25.1
Bumps [django-bootstrap3](https://github.com/zostera/django-bootstrap3) from 24.3 to 25.1.
- [Changelog](https://github.com/zostera/django-bootstrap3/blob/main/CHANGELOG.md)
- [Commits](https://github.com/zostera/django-bootstrap3/compare/v24.3...v25.1)

---
updated-dependencies:
- dependency-name: django-bootstrap3
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-03 13:41:42 +01:00
dependabot[bot] e236dc275d Bump @babel/core from 7.26.7 to 7.26.9 in /src/pretix/static/npm_dir
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.26.7 to 7.26.9.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.26.9/packages/babel-core)

---
updated-dependencies:
- dependency-name: "@babel/core"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-03 13:41:25 +01:00
Robert Rigo aa38163096 Translations: Update Croatian
Currently translated at 84.4% (4943 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/hr/

powered by weblate
2025-03-03 13:40:12 +01:00
Kristian Feldsam e56eb2df4f Translations: Update Slovak
Currently translated at 90.0% (5269 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/sk/

powered by weblate
2025-03-03 13:40:12 +01:00
Robert Rigo d851885d16 Translations: Update Croatian
Currently translated at 84.4% (4942 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/hr/

powered by weblate
2025-03-03 13:40:12 +01:00
Tim Maurizio Dullaart a2955b4579 Translations: Update Dutch
Currently translated at 77.4% (182 of 235 strings)

Translation: pretix/pretix (JavaScript parts)
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix-js/nl/

powered by weblate
2025-03-03 13:40:12 +01:00
Tim Maurizio Dullaart a7cd739555 Translations: Update Dutch
Currently translated at 98.4% (5763 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/nl/

powered by weblate
2025-03-03 13:40:12 +01:00
Kristian Feldsam d9d5795837 Translations: Update Slovak
Currently translated at 90.0% (5269 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/sk/

powered by weblate
2025-03-03 13:40:12 +01:00
Kristian Feldsam 886f7f6178 Translations: Update Slovak
Currently translated at 30.6% (72 of 235 strings)

Translation: pretix/pretix (JavaScript parts)
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix-js/sk/

powered by weblate
2025-03-03 13:40:12 +01:00
Kristian Feldsam b66bbf7936 Translations: Update Slovak
Currently translated at 90.0% (5269 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/sk/

powered by weblate
2025-03-03 13:40:12 +01:00
CVZ-es cb4ca80704 Translations: Update Spanish
Currently translated at 100.0% (5853 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/es/

powered by weblate
2025-03-03 13:40:12 +01:00
CVZ-es bf7b0d6c21 Translations: Update French
Currently translated at 100.0% (5853 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/fr/

powered by weblate
2025-03-03 13:40:12 +01:00
Renne Rocha 5cd97d6021 Translations: Update Portuguese (Brazil)
Currently translated at 55.9% (3273 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/pt_BR/

powered by weblate
2025-03-03 13:40:12 +01:00
Renne Rocha 15c3b44395 Translations: Update Portuguese (Brazil)
Currently translated at 55.5% (3254 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/pt_BR/

powered by weblate
2025-02-28 16:14:14 +01:00
Renne Rocha 75b703b62f Translations: Update Portuguese (Brazil)
Currently translated at 53.8% (3153 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/pt_BR/

powered by weblate
2025-02-28 16:14:14 +01:00
Elisabetta D'Agostino 3446986434 Translations: Update Italian
Currently translated at 24.4% (1430 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/it/

powered by weblate
2025-02-28 16:14:14 +01:00
Renne Rocha 05dc2a1c19 Translations: Update Portuguese (Brazil)
Currently translated at 100.0% (235 of 235 strings)

Translation: pretix/pretix (JavaScript parts)
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix-js/pt_BR/

powered by weblate
2025-02-28 16:14:14 +01:00
Cornelius Kibelka 631771aa4b Translations: Update Portuguese (Brazil)
Currently translated at 52.1% (3053 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/pt_BR/

powered by weblate
2025-02-28 16:14:14 +01:00
Renne Rocha de142e1c97 Translations: Update Portuguese (Brazil)
Currently translated at 52.1% (3053 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/pt_BR/

powered by weblate
2025-02-28 16:14:14 +01:00
Cornelius Kibelka d5fd5edf11 Translations: Update Portuguese (Brazil)
Currently translated at 48.7% (2853 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/pt_BR/

powered by weblate
2025-02-28 16:14:14 +01:00
Renne Rocha c6356b439b Translations: Update Portuguese (Brazil)
Currently translated at 48.7% (2853 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/pt_BR/

powered by weblate
2025-02-28 16:14:14 +01:00
Renne Rocha 0381f94841 Translations: Update Portuguese (Brazil)
Currently translated at 99.5% (234 of 235 strings)

Translation: pretix/pretix (JavaScript parts)
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix-js/pt_BR/

powered by weblate
2025-02-28 16:14:14 +01:00
Renne Rocha a4b69b9d9f Translations: Update Portuguese (Brazil)
Currently translated at 37.2% (2180 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/pt_BR/

powered by weblate
2025-02-28 16:14:14 +01:00
Raphael Michel 79975e6174 Widget: Fix opening a subevent dynamically (#4876) 2025-02-28 11:18:11 +01:00
Mira 012eda66bd Blocklist USN currency (#4879) 2025-02-28 10:18:39 +01:00
Richard Schreiber 018569a0d6 [A11y] Remove all autofocus in control except login/auth and dashboard 2025-02-28 08:56:54 +01:00
Raphael Michel 625bc66516 Bump version to 2025.3.0.dev0 2025-02-25 17:19:53 +01:00
Raphael Michel 946777bd64 Bump version to 2025.2.0 2025-02-25 17:17:49 +01:00
Raphael Michel 982069720e Change links to new documentation 2025-02-25 17:17:02 +01:00
Raphael Michel f450abba24 Fix crash in voucher bulk deletion (PRETIXEU-B0T) 2025-02-25 16:00:53 +01:00
Raphael Michel 11632e082f API: Allow to add a fee to an order (#4806) (#4829)
* API: Allow to add a fee to an order (#4806)

* Fix example in docs

* Consistent order of examples

* Add create_fees to example

* docs: None -> null

* docs: update fee_type options

---------

Co-authored-by: Mira Weller <weller@rami.io>
2025-02-25 14:41:28 +01:00
Martin Gross 083e5ed265 New Signal: order_expiry_changed (#4867)
Co-authored-by: Raphael Michel <michel@rami.io>
2025-02-25 13:38:26 +01:00
Raphael Michel b48259ab60 Translations: Update German (informal) (de_Informal)
Currently translated at 100.0% (5853 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/de_Informal/

powered by weblate
2025-02-25 13:33:57 +01:00
Raphael Michel acf200da39 Translations: Update German
Currently translated at 100.0% (5853 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/de/

powered by weblate
2025-02-25 13:33:57 +01:00
Raphael Michel b46db4b47a Translations: Update German (informal) (de_Informal)
Currently translated at 100.0% (5853 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/de_Informal/

powered by weblate
2025-02-25 13:33:57 +01:00
Raphael Michel 5cacb40d96 Translations: Update German
Currently translated at 100.0% (5853 of 5853 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/de/

powered by weblate
2025-02-25 13:33:57 +01:00
Raphael Michel efac98e98d Update wordlist 2025-02-25 12:52:31 +01:00
Raphael Michel a56033bfb0 Update wordlist 2025-02-25 12:50:53 +01:00
Raphael Michel dfdeaabb71 Update po files
[CI skip]

Signed-off-by: Raphael Michel <michel@rami.io>
2025-02-25 11:10:20 +01:00
262 changed files with 170072 additions and 156425 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
{
"contributors": "https://crm.rami.io/cla/check/?project=pretix&checkContributor=",
"message": "Hey there! :) Thank you very much for offering a contribution to pretix! For legal reasons, we need you to sign a Contributor License Agreement in order to be able to merge the code. Sorry for the hassle :( Please download the agreement from https://pretix.eu/about/en/cla and send a signed copy to support@pretix.eu. Feel free to also contact us there or via comments here if you have any questions!",
"message": "Hey there! :) Thank you very much for offering a contribution to pretix! For legal reasons, we need you to sign a Contributor License Agreement in order to be able to merge the code. Sorry for the hassle :( Please download the agreement from https://pretix.eu/about/en/cla and send a signed copy to support@pretix.eu. Feel free to also contact us there or via comments here if you have any questions!\n\nFeel free to ignore me on documentation changes, translations, and trivial PRs like typo fixes (and similar single-line changes) we can merge these without a CLA as well.",
"label": "cla-signed"
}
+1 -1
View File
@@ -1,5 +1,5 @@
Code of Conduct
===============
We have a [Code of Conduct](https://docs.pretix.eu/en/latest/development/contribution/codeofconduct.html)
We have a [Code of Conduct](https://docs.pretix.eu/dev/development/contribution/codeofconduct.html)
in place that applies to all project contributions, including issues, pull requests, etc.
+3 -3
View File
@@ -3,9 +3,9 @@ Contributing to pretix
Hey there and welcome to pretix!
* We've got a contributors guide in [our documentation](https://docs.pretix.eu/en/latest/development/contribution/) together with notes on the [development setup](https://docs.pretix.eu/en/latest/development/setup.html).
* We've got a contributors guide in [our documentation](https://docs.pretix.eu/dev/development/contribution/) together with notes on the [development setup](https://docs.pretix.eu/dev/development/setup.html).
* Please note that we have a [Code of Conduct](https://docs.pretix.eu/en/latest/development/contribution/codeofconduct.html) in place that applies to all project contributions, including issues, pull requests, etc.
* Please note that we have a [Code of Conduct](https://docs.pretix.eu/dev/development/contribution/codeofconduct.html) in place that applies to all project contributions, including issues, pull requests, etc.
* Before we can accept a PR from you we'll need you to sign [our CLA](https://pretix.eu/about/en/cla). You can find more information about the how and why in our [License FAQ](https://docs.pretix.eu/en/latest/license/faq.html#) and in our [license change blog post](https://pretix.eu/about/en/blog/20210412-license/).
* Before we can accept a PR from you we'll need you to sign [our CLA](https://pretix.eu/about/en/cla). You can find more information about the how and why in our [License FAQ](https://docs.pretix.eu/trust/licensing/faq/) and in our [license change blog post](https://pretix.eu/about/en/blog/20210412-license/).
+4 -4
View File
@@ -5,7 +5,7 @@ pretix
:target: https://pypi.python.org/pypi/pretix
.. image:: https://github.com/pretix/pretix/workflows/Documentation/badge.svg
:target: https://docs.pretix.eu/en/latest/
:target: https://docs.pretix.eu/
.. image:: https://github.com/pretix/pretix/workflows/Tests/badge.svg
@@ -56,8 +56,8 @@ License
The code in this repository is covered by different licenses. Most of it is available to everyone under the terms of
the GNU AGPL license v3 with additional terms. See the LICENSE file for the complete license details.
.. _installation guide: https://docs.pretix.eu/en/latest/admin/installation/index.html
.. _developer documentation: https://docs.pretix.eu/en/latest/development/index.html
.. _Code of Conduct: https://docs.pretix.eu/en/latest/development/contribution/codeofconduct.html
.. _installation guide: https://docs.pretix.eu/self-hosting/installation/general/
.. _developer documentation: https://docs.pretix.eu/dev/development/index.html
.. _Code of Conduct: https://docs.pretix.eu/dev/development/contribution/codeofconduct.html
.. _pretix.eu: https://pretix.eu
.. _blog: https://pretix.eu/about/en/blog/
+2 -2
View File
@@ -23,7 +23,7 @@ Certificate download
.. sourcecode:: http
GET /api/v1/organizers/bigevents/events/sampleconf/orderpositions/23442/download/certificate/ HTTP/1.1
GET /api/v1/organizers/bigevents/events/sampleconf/orderpositions/23442/certificate/ HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
@@ -38,7 +38,7 @@ Certificate download
.. sourcecode:: http
GET /api/v1/organizers/bigevents/events/sampleconf/orderpositions/23442/download/certificate/?result=1f550651-ae7b-4911-a76c-2be8f348aaa5 HTTP/1.1
GET /api/v1/organizers/bigevents/events/sampleconf/orderpositions/23442/certificate/?result=1f550651-ae7b-4911-a76c-2be8f348aaa5 HTTP/1.1
Host: pretix.eu
Accept: application/json, text/javascript
+8 -1
View File
@@ -54,6 +54,11 @@ Checking a ticket in
this request twice with the same nonce, the second request will also succeed but will always
create only one check-in object even when the previous request was successful as well. This
allows for a certain level of idempotency and enables you to re-try after a connection failure.
:<json boolean use_order_locale: Specifies that pretix should use the customer's language (``locale`` field from the
order) when building texts (currently only the ``reason_explanation`` response field).
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 string status: ``"ok"``, ``"incomplete"``, 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.
@@ -62,7 +67,9 @@ Checking a ticket in
will only include check-ins for the selected list. (2) An additional boolean property
``require_attention`` will inform you whether either the order or the item have the
``checkin_attention`` flag set. (3) If ``attendee_name`` is empty, it may automatically fall
back to values from a parent product or from invoice addresses.
back to values from a parent product or from invoice addresses. (4) Additional properties
``order__status``, ``order__valid_if_pending``, ``order__require_approval``, and
``order__locale`` are included with details form the order for convenience.
:>json boolean require_attention: Whether or not the ``require_attention`` flag is set on the item or order.
:>json list checkin_texts: List of additional texts to show to the user.
:>json object list: Excerpt of information about the matching :ref:`check-in list <rest-checkinlists>` (if any was found),
+14
View File
@@ -35,6 +35,10 @@ subevent_mode strings Determines h
``"same"`` (discount is only applied for groups within
the same date), or ``"distinct"`` (discount is only applied
for groups with no two same dates).
subevent_date_from datetime The first date time of a subevent to which this discount can be applied
(or ``null``). Ignored in non-series events.
subevent_date_until datetime The last date time of a subevent to which this discount can be applied
(or ``null``). Ignored in non-series events.
condition_all_products boolean If ``true``, the discount condition applies to all items.
condition_limit_products list of integers If ``condition_all_products`` is not set, this is a list
of internal item IDs that the discount condition applies to.
@@ -105,6 +109,8 @@ Endpoints
"available_from": null,
"available_until": null,
"subevent_mode": "mixed",
"subevent_date_from": null,
"subevent_date_until": null,
"condition_all_products": true,
"condition_limit_products": [],
"condition_apply_to_addons": true,
@@ -163,6 +169,8 @@ Endpoints
"available_from": null,
"available_until": null,
"subevent_mode": "mixed",
"subevent_date_from": null,
"subevent_date_until": null,
"condition_all_products": true,
"condition_limit_products": [],
"condition_apply_to_addons": true,
@@ -207,6 +215,8 @@ Endpoints
"available_from": null,
"available_until": null,
"subevent_mode": "mixed",
"subevent_date_from": null,
"subevent_date_until": null,
"condition_all_products": true,
"condition_limit_products": [],
"condition_apply_to_addons": true,
@@ -240,6 +250,8 @@ Endpoints
"available_from": null,
"available_until": null,
"subevent_mode": "mixed",
"subevent_date_from": null,
"subevent_date_until": null,
"condition_all_products": true,
"condition_limit_products": [],
"condition_apply_to_addons": true,
@@ -302,6 +314,8 @@ Endpoints
"available_from": null,
"available_until": null,
"subevent_mode": "mixed",
"subevent_date_from": null,
"subevent_date_until": null,
"condition_all_products": true,
"condition_limit_products": [],
"condition_apply_to_addons": true,
+33 -15
View File
@@ -75,8 +75,9 @@ positions list of objects List of order p
fees list of objects List of fees included in the order total. By default, only
non-canceled fees are included.
├ id integer Internal ID of the fee record
├ fee_type string Type of fee (currently ``payment``, ``passbook``,
``other``)
├ fee_type string Type of fee (currently ``payment``, ``shipping``,
``service``, ``cancellation``, ``insurance``, ``late``,
``other``, ``giftcard``)
├ value money (string) Fee amount
├ description string Human-readable string with more details (can be empty)
├ internal_type string Internal string (i.e. ID of the payment provider),
@@ -1942,9 +1943,14 @@ Manipulating individual positions
* ``valid_until``
* ``secret``
Changing parameters such as ``item`` or ``price`` will **not** automatically trigger creation of a new invoice,
you need to take care of that yourself.
Changing ``secret`` does not cause a new PDF ticket to be sent to the customer, nor does it cause the old secret
to be added to the revocation list, even if your ticket generator uses one.
**Example request**:
.. sourcecode:: http
@@ -2244,6 +2250,9 @@ otherwise, such as splitting an order or changing fees.
* ``cancel_fees``: A list of objects with the single key ``fee`` specifying an order fee ID.
* ``create_fees``: A list of objects describing new order fees with the fields ``fee_type``, ``value``, ``description``,
``internal_type``, ``tax_rule``
* ``recalculate_taxes``: If set to ``"keep_net"``, all taxes will be recalculated based on the tax rule and invoice
address, the net price will be kept. If set to ``"keep_gross"``, the gross price will be kept. If set to ``null``
(the default) the taxes are not recalculated.
@@ -2263,17 +2272,12 @@ otherwise, such as splitting an order or changing fees.
Content-Type: application/json
{
"cancel_positions": [
{
"position": 12373
}
],
"patch_positions": [
{
"position": 12374,
"body": {
"item": 12,
"variation": None,
"variation": null,
"subevent": 562,
"seat": "seat-guid-2",
"price": "99.99",
@@ -2281,6 +2285,11 @@ otherwise, such as splitting an order or changing fees.
}
}
],
"cancel_positions": [
{
"position": 12373
}
],
"split_positions": [
{
"position": 12375
@@ -2289,7 +2298,7 @@ otherwise, such as splitting an order or changing fees.
"create_positions": [
{
"item": 12,
"variation": None,
"variation": null,
"subevent": 562,
"seat": "seat-guid-2",
"price": "99.99",
@@ -2297,12 +2306,7 @@ otherwise, such as splitting an order or changing fees.
"attendee_name": "Peter",
}
],
"cancel_fees": [
{
"fee": 49
}
],
"change_fees": [
"patch_fees": [
{
"fee": 51,
"body": {
@@ -2310,6 +2314,20 @@ otherwise, such as splitting an order or changing fees.
}
}
],
"cancel_fees": [
{
"fee": 49
}
],
"create_fees": [
{
"fee_type": "other",
"value": "1.50",
"description": "Example Fee",
"internal_type": "",
"tax_rule": 15
}
],
"reissue_invoice": true,
"send_email": true,
"recalculate_taxes": "keep_gross"
+1 -1
View File
@@ -23,7 +23,7 @@ There are multiple signals that will be sent out in the ordering cycle:
.. automodule:: pretix.base.signals
:no-index:
:members: validate_cart, validate_cart_addons, validate_order, order_valid_if_pending, order_fee_calculation, order_paid, order_placed, order_canceled, order_reactivated, order_expired, order_modified, order_changed, order_approved, order_denied, order_fee_type_name, allow_ticket_download, order_split, order_gracefully_delete, invoice_line_text
:members: validate_cart, validate_cart_addons, validate_order, order_valid_if_pending, order_fee_calculation, order_paid, order_placed, order_canceled, order_reactivated, order_expired, order_expiry_changed, order_modified, order_changed, order_approved, order_denied, order_fee_type_name, allow_ticket_download, order_split, order_gracefully_delete, invoice_line_text
Check-ins
"""""""""
+24
View File
@@ -84,6 +84,8 @@ A working example would be:
restricted = False
description = _("This plugin allows you to receive payments via PayPal")
compatibility = "pretix>=2.7.0"
settings_links = []
navigation_links = []
default_app_config = 'pretix_paypal.PaypalApp'
@@ -185,6 +187,28 @@ your Django app label.
with checking that the calling user is logged in, has appropriate permissions,
etc. We plan on providing native support for this in a later version.
To make your plugin views easily discoverable, you can specify links for "Go to"
and "Settings" buttons next to your entry on the plugin page. These links should be
added to the ``navigation_links`` and ``settings_links``, respectively, in the
``PretixPluginMeta`` class.
Each array entry consists of a tuple ``(label, urlname, kwargs)``. For the label,
either a string or a tuple of strings can be specified. In the latter case, the provided
strings will be merged with a separator indicating they are successive navigation steps
the user would need to take to reach the page via the regular menu
(e.g. "Payment > Bank transfer" as below).
.. code-block:: python
settings_links = [
((_("Payment"), _("Bank transfer")), "control:event.settings.payment.provider", {"provider": "banktransfer"}),
]
navigation_links = [
((_("Bank transfer"), _("Import bank data")), "plugins:banktransfer:import", {}),
((_("Bank transfer"), _("Export refunds")), "plugins:banktransfer:refunds.list", {}),
]
.. _Django app: https://docs.djangoproject.com/en/3.0/ref/applications/
.. _signal dispatcher: https://docs.djangoproject.com/en/3.0/topics/signals/
.. _namespace packages: https://legacy.python.org/dev/peps/pep-0420/
+16 -16
View File
@@ -30,13 +30,13 @@ dependencies = [
"babel",
"BeautifulSoup4==4.13.*",
"bleach==6.2.*",
"celery==5.4.*",
"celery==5.5.*",
"chardet==5.2.*",
"cryptography>=44.0.0",
"css-inline==0.14.*",
"defusedcsv>=1.1.0",
"Django[argon2]==4.2.*,>=4.2.15",
"django-bootstrap3==24.3",
"django-bootstrap3==25.1",
"django-compressor==4.5.1",
"django-countries==7.6.*",
"django-filter==25.1",
@@ -49,22 +49,22 @@ dependencies = [
"django-localflavor==4.0",
"django-markup",
"django-oauth-toolkit==2.3.*",
"django-otp==1.5.*",
"django-otp==1.6.*",
"django-phonenumber-field==7.3.*",
"django-redis==5.4.*",
"django-scopes==2.0.*",
"django-statici18n==2.6.*",
"djangorestframework==3.15.*",
"djangorestframework==3.16.*",
"dnspython==2.7.*",
"drf_ujson2==1.7.*",
"geoip2==5.*",
"importlib_metadata==8.*", # Polyfill, we can probably drop this once we require Python 3.10+
"isoweek",
"jsonschema",
"kombu==5.4.*",
"kombu==5.5.*",
"libsass==0.23.*",
"lxml",
"markdown==3.7", # 3.3.5 requires importlib-metadata>=4.4, but django-bootstrap3 requires importlib-metadata<3.
"markdown==3.8", # 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.2.*",
@@ -73,25 +73,25 @@ dependencies = [
"paypalrestsdk==1.13.*",
"paypal-checkout-serversdk==1.0.*",
"PyJWT==2.10.*",
"phonenumberslite==8.13.*",
"Pillow==11.1.*",
"phonenumberslite==9.0.*",
"Pillow==11.2.*",
"pretix-plugin-build",
"protobuf==5.29.*",
"protobuf==6.30.*",
"psycopg2-binary",
"pycountry",
"pycparser==2.22",
"pycryptodome==3.21.*",
"pypdf==5.1.*",
"pycryptodome==3.22.*",
"pypdf==5.4.*",
"python-bidi==0.6.*", # Support for Arabic in reportlab
"python-dateutil==2.9.*",
"pytz",
"pytz-deprecation-shim==0.1.*",
"pyuca",
"qrcode==8.0",
"qrcode==8.2",
"redis==5.2.*",
"reportlab==4.3.*",
"reportlab==4.4.*",
"requests==2.31.*",
"sentry-sdk==2.22.*",
"sentry-sdk==2.27.*",
"sepaxml==2.6.*",
"stripe==7.9.*",
"text-unidecode==1.*",
@@ -111,10 +111,10 @@ dev = [
"coverage",
"coveralls",
"fakeredis==2.26.*",
"flake8==7.1.*",
"flake8==7.2.*",
"freezegun",
"isort==6.0.*",
"pep8-naming==0.14.*",
"pep8-naming==0.15.*",
"potypo",
"pytest-asyncio>=0.24",
"pytest-cache",
+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__ = "2025.2.0.dev0"
__version__ = "2025.5.0.dev0"
+2 -1
View File
@@ -121,6 +121,7 @@ LANGUAGES_OFFICIAL = {
'en', 'de', 'de-informal'
}
LANGUAGES_RTL = {
# When adding more right-to-left languages, also update pretix/static/pretixbase/scss/_rtl.scss
'ar', 'hw'
}
LANGUAGES_INCUBATING = {
@@ -259,7 +260,7 @@ COMPRESS_FILTERS = {
CURRENCIES = [
c for c in currencies
if c.alpha_3 not in {
'XAG', 'XAU', 'XBA', 'XBB', 'XBC', 'XBD', 'XDR', 'XPD', 'XPT', 'XSU', 'XTS', 'XUA',
'USN', 'XAG', 'XAU', 'XBA', 'XBB', 'XBC', 'XBD', 'XDR', 'XPD', 'XPT', 'XSU', 'XTS', 'XUA',
}
]
CURRENCY_PLACES = {
+9 -1
View File
@@ -81,6 +81,13 @@ class SalesChannelMigrationMixin:
def to_internal_value(self, data):
if "sales_channels" in data:
if data["sales_channels"] is None:
raise ValidationError({
"sales_channels": [
"The legacy attribute 'sales_channels' cannot be set to None, it must be a list."
]
})
prefetch_related_objects([self.organizer], "sales_channels")
all_channels = {
s.identifier for s in
@@ -89,7 +96,7 @@ class SalesChannelMigrationMixin:
if data.get("all_sales_channels") and set(data["sales_channels"]) != all_channels:
raise ValidationError({
"limit_sales_channels": [
"all_sales_channels": [
"If 'all_sales_channels' is set, the legacy attribute 'sales_channels' must not be set or set to "
"the list of all sales channels."
]
@@ -109,6 +116,7 @@ class SalesChannelMigrationMixin:
else:
data["all_sales_channels"] = False
data["limit_sales_channels"] = data["sales_channels"]
del data["sales_channels"]
if data.get("all_sales_channels"):
+1 -1
View File
@@ -176,7 +176,7 @@ class BaseCartPositionCreateSerializer(I18nAwareModelSerializer):
def create(self, validated_data):
validated_data.pop('_quotas')
answers_data = validated_data.pop('answers')
answers_data = validated_data.pop('answers', [])
attendee_name = validated_data.pop('attendee_name', '')
if attendee_name and not validated_data.get('attendee_name_parts'):
+1
View File
@@ -84,6 +84,7 @@ class CheckinRPCRedeemInputSerializer(serializers.Serializer):
type = serializers.ChoiceField(choices=Checkin.CHECKIN_TYPES, default=Checkin.TYPE_ENTRY)
ignore_unpaid = serializers.BooleanField(default=False, required=False)
questions_supported = serializers.BooleanField(default=True, required=False)
use_order_locale = serializers.BooleanField(default=False, required=False)
nonce = serializers.CharField(required=False, allow_null=True)
datetime = serializers.DateTimeField(required=False, allow_null=True)
answers = serializers.JSONField(required=False, allow_null=True)
+6 -5
View File
@@ -38,11 +38,12 @@ class DiscountSerializer(SalesChannelMigrationMixin, I18nAwareModelSerializer):
class Meta:
model = Discount
fields = ('id', 'active', 'internal_name', 'position', 'all_sales_channels', 'limit_sales_channels',
'available_from', 'available_until', 'subevent_mode', 'condition_all_products',
'condition_limit_products', 'condition_apply_to_addons', 'condition_min_count', 'condition_min_value',
'benefit_discount_matching_percent', 'benefit_only_apply_to_cheapest_n_matches',
'benefit_same_products', 'benefit_limit_products', 'benefit_apply_to_addons',
'benefit_ignore_voucher_discounted', 'condition_ignore_voucher_discounted')
'available_from', 'available_until', 'subevent_mode', 'subevent_date_from', 'subevent_date_until',
'condition_all_products', 'condition_limit_products', 'condition_apply_to_addons',
'condition_min_count', 'condition_min_value', 'benefit_discount_matching_percent',
'benefit_only_apply_to_cheapest_n_matches', 'benefit_same_products', 'benefit_limit_products',
'benefit_apply_to_addons', 'benefit_ignore_voucher_discounted',
'condition_ignore_voucher_discounted')
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
+4 -2
View File
@@ -607,6 +607,7 @@ class CheckinListOrderPositionSerializer(OrderPositionSerializer):
order__status = serializers.SlugRelatedField(read_only=True, slug_field='status', source='order')
order__valid_if_pending = serializers.SlugRelatedField(read_only=True, slug_field='valid_if_pending', source='order')
order__require_approval = serializers.SlugRelatedField(read_only=True, slug_field='require_approval', source='order')
order__locale = serializers.SlugRelatedField(read_only=True, slug_field='locale', source='order')
class Meta:
model = OrderPosition
@@ -615,7 +616,7 @@ class CheckinListOrderPositionSerializer(OrderPositionSerializer):
'attendee_email', 'voucher', 'tax_rate', 'tax_value', 'secret', 'addon_to', 'subevent', 'checkins',
'print_logs', 'downloads', 'answers', 'tax_rule', 'pseudonymization_id', 'pdf_data', 'seat',
'require_attention', 'order__status', 'order__valid_if_pending', 'order__require_approval',
'valid_from', 'valid_until', 'blocked')
'order__locale', 'valid_from', 'valid_until', 'blocked')
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
@@ -1518,7 +1519,8 @@ class OrderCreateSerializer(I18nAwareModelSerializer):
self.context['event'],
order.sales_channel,
[
(cp.item_id, cp.subevent_id, cp.price, bool(cp.addon_to), cp.is_bundled, pos._voucher_discount)
(cp.item_id, cp.subevent_id, cp.subevent.date_from if cp.subevent_id else None, cp.price,
bool(cp.addon_to), cp.is_bundled, pos._voucher_discount)
for cp in order_positions
]
)
+57 -2
View File
@@ -30,7 +30,7 @@ from rest_framework.exceptions import ValidationError
from pretix.api.serializers.order import (
AnswerCreateSerializer, AnswerSerializer, CompatibleCountryField,
OrderPositionCreateSerializer,
OrderFeeCreateSerializer, OrderPositionCreateSerializer,
)
from pretix.base.models import ItemVariation, Order, OrderFee, OrderPosition
from pretix.base.services.orders import OrderError
@@ -104,6 +104,54 @@ class OrderPositionCreateForExistingOrderSerializer(OrderPositionCreateSerialize
raise ValidationError(str(e))
class OrderFeeCreateForExistingOrderSerializer(OrderFeeCreateSerializer):
order = serializers.SlugRelatedField(slug_field='code', queryset=Order.objects.none(), required=True, allow_null=False)
value = serializers.DecimalField(required=True, allow_null=False, decimal_places=2,
max_digits=13)
internal_type = serializers.CharField(required=False, default="")
class Meta:
model = OrderFee
fields = ('order', 'fee_type', 'value', 'description', 'internal_type', 'tax_rule')
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if not self.context:
return
self.fields['order'].queryset = self.context['event'].orders.all()
self.fields['tax_rule'].queryset = self.context['event'].tax_rules.all()
if 'order' in self.context:
del self.fields['order']
def validate(self, data):
data = super().validate(data)
if 'order' in self.context:
data['order'] = self.context['order']
return data
def create(self, validated_data):
ocm = self.context['ocm']
try:
f = OrderFee(
order=validated_data['order'],
fee_type=validated_data['fee_type'],
value=validated_data.get('value'),
description=validated_data.get('description'),
internal_type=validated_data.get('internal_type'),
tax_rule=validated_data.get('tax_rule'),
)
f._calculate_tax()
ocm.add_fee(f)
if self.context.get('commit', True):
ocm.commit()
return validated_data['order'].fees.order_by('-pk').first()
else:
return OrderFee() # fake to appease DRF
except OrderError as e:
raise ValidationError(str(e))
class OrderPositionInfoPatchSerializer(serializers.ModelSerializer):
answers = AnswerSerializer(many=True)
country = CompatibleCountryField(source='*')
@@ -203,7 +251,7 @@ class OrderPositionChangeSerializer(serializers.ModelSerializer):
class Meta:
model = OrderPosition
fields = (
'item', 'variation', 'subevent', 'seat', 'price', 'tax_rule', 'valid_from', 'valid_until'
'item', 'variation', 'subevent', 'seat', 'price', 'tax_rule', 'valid_from', 'valid_until', 'secret'
)
def __init__(self, *args, **kwargs):
@@ -271,6 +319,7 @@ class OrderPositionChangeSerializer(serializers.ModelSerializer):
tax_rule = validated_data.get('tax_rule', instance.tax_rule)
valid_from = validated_data.get('valid_from', instance.valid_from)
valid_until = validated_data.get('valid_until', instance.valid_until)
secret = validated_data.get('secret', instance.secret)
change_item = None
if item != instance.item or variation != instance.variation:
@@ -303,6 +352,9 @@ class OrderPositionChangeSerializer(serializers.ModelSerializer):
if valid_until != instance.valid_until:
ocm.change_valid_until(instance, valid_until)
if secret != instance.secret:
ocm.change_ticket_secret(instance, secret)
if self.context.get('commit', True):
ocm.commit()
instance.refresh_from_db()
@@ -401,6 +453,9 @@ class OrderChangeOperationSerializer(serializers.Serializer):
self.fields['split_positions'] = SelectPositionSerializer(
many=True, required=False, context=self.context
)
self.fields['create_fees'] = OrderFeeCreateForExistingOrderSerializer(
many=True, required=False, context=self.context
)
self.fields['patch_fees'] = PatchFeeSerializer(
many=True, required=False, context=self.context
)
+8 -2
View File
@@ -165,6 +165,7 @@ class CheckinListViewSet(viewsets.ModelViewSet):
if not serializer.validated_data.get('position'):
kwargs['position'] = OrderPosition.all.filter(
order__event=self.request.event,
secret=serializer.validated_data['raw_barcode']
).first()
@@ -419,7 +420,7 @@ def _checkin_list_position_queryset(checkinlists, ignore_status=False, ignore_pr
def _redeem_process(*, checkinlists, raw_barcode, answers_data, datetime, force, checkin_type, ignore_unpaid, nonce,
untrusted_input, user, auth, expand, pdf_data, request, questions_supported, canceled_supported,
source_type='barcode', legacy_url_support=False, simulate=False, gate=None):
source_type='barcode', legacy_url_support=False, simulate=False, gate=None, use_order_locale=False):
if not checkinlists:
raise ValidationError('No check-in list passed.')
@@ -693,7 +694,11 @@ def _redeem_process(*, checkinlists, raw_barcode, answers_data, datetime, force,
pass
# 6. Pass to our actual check-in logic
with language(op.order.event.settings.locale):
if use_order_locale:
locale = op.order.locale
else:
locale = op.order.event.settings.locale
with language(locale):
try:
perform_checkin(
op=op,
@@ -908,6 +913,7 @@ class CheckinRPCRedeemView(views.APIView):
expand=self.request.query_params.getlist('expand'),
pdf_data=self.request.query_params.get('pdf_data', 'false') == 'true',
questions_supported=s.validated_data['questions_supported'],
use_order_locale=s.validated_data['use_order_locale'],
canceled_supported=True,
request=self.request, # this is not clean, but we need it in the serializers for URL generation
legacy_url_support=False,
+12 -6
View File
@@ -63,7 +63,8 @@ from pretix.api.serializers.order import (
)
from pretix.api.serializers.orderchange import (
BlockNameSerializer, OrderChangeOperationSerializer,
OrderFeeChangeSerializer, OrderPositionChangeSerializer,
OrderFeeChangeSerializer, OrderFeeCreateForExistingOrderSerializer,
OrderPositionChangeSerializer,
OrderPositionCreateForExistingOrderSerializer,
OrderPositionInfoPatchSerializer,
)
@@ -184,7 +185,7 @@ with scopes_disabled():
| Q(full_invoice_no__iexact=u)
).values_list('order_id', flat=True)
matching_positions = OrderPosition.objects.filter(
matching_positions = OrderPosition.all.filter(
Q(order=OuterRef('pk')) & Q(
Q(attendee_name_cached__icontains=u) | Q(attendee_email__icontains=u)
| Q(secret__istartswith=u)
@@ -451,10 +452,9 @@ class EventOrderViewSet(OrderViewSetMixin, viewsets.ModelViewSet):
comment = request.data.get('comment', None)
cancellation_fee = request.data.get('cancellation_fee', None)
if cancellation_fee:
try:
cancellation_fee = float(Decimal(cancellation_fee))
except:
cancellation_fee = None
cancellation_fee = serializers.DecimalField(max_digits=13, decimal_places=2).to_internal_value(
cancellation_fee,
)
order = self.get_object()
if not order.cancel_allowed():
@@ -988,6 +988,12 @@ class EventOrderViewSet(OrderViewSetMixin, viewsets.ModelViewSet):
ocm.cancel_fee(r['fee'])
canceled_fees.add(r['fee'])
for r in serializer.validated_data.get('create_fees', []):
pos_serializer = OrderFeeCreateForExistingOrderSerializer(
context={'ocm': ocm, 'commit': False, 'event': request.event, **self.get_serializer_context()},
)
pos_serializer.create(r)
for r in serializer.validated_data.get('patch_fees', []):
if r['fee'] in canceled_fees:
continue
+1 -1
View File
@@ -712,7 +712,7 @@ class OrderListExporter(MultiSheetListExporter):
if name_scheme and len(name_scheme['fields']) > 1:
for k, label, w in name_scheme['fields']:
row.append(
get_name_parts_localized(op.attendee_name_parts, k)
get_name_parts_localized(op.attendee_name_parts, k) if op.attendee_name_parts else ''
)
row += [
op.attendee_email,
+3 -3
View File
@@ -93,7 +93,7 @@ class MarkdownTextarea(forms.Textarea):
'<div class="i18n-form-group">%s<div class="i18n-field-markdown-note">%s</div></div>' % (
super()._render(template_name, context, renderer=None),
_("You can use {markup_name} in this field.").format(
markup_name='<a href="https://docs.pretix.eu/en/latest/user/markdown.html" target="_blank">Markdown</a>'
markup_name='<a href="https://docs.pretix.eu/guides/markdown/" target="_blank">Markdown</a>'
)
)
)
@@ -104,7 +104,7 @@ class I18nMarkdownTextarea(i18nfield.forms.I18nTextarea):
rendered_widgets = rendered_widgets + [
'<div class="i18n-field-markdown-note">%s</div>' % (
_("You can use {markup_name} in this field.").format(
markup_name='<a href="https://docs.pretix.eu/en/latest/user/markdown.html" target="_blank">Markdown</a>'
markup_name='<a href="https://docs.pretix.eu/guides/markdown/" target="_blank">Markdown</a>'
)
)
]
@@ -116,7 +116,7 @@ class I18nMarkdownTextInput(i18nfield.forms.I18nTextInput):
rendered_widgets = rendered_widgets + [
'<div class="i18n-field-markdown-note">%s</div>' % (
_("You can use {markup_name} in this field.").format(
markup_name='<a href="https://docs.pretix.eu/en/latest/user/markdown.html" target="_blank">Markdown</a>'
markup_name='<a href="https://docs.pretix.eu/guides/markdown/" target="_blank">Markdown</a>'
)
)
]
+54 -7
View File
@@ -58,6 +58,7 @@ from django.urls import reverse
from django.utils.formats import date_format
from django.utils.html import escape
from django.utils.safestring import mark_safe
from django.utils.text import format_lazy
from django.utils.timezone import get_current_timezone
from django.utils.translation import gettext_lazy as _, pgettext_lazy
from django_countries import countries
@@ -83,8 +84,8 @@ from pretix.base.services.tax import (
VATIDFinalError, VATIDTemporaryError, validate_vat_id,
)
from pretix.base.settings import (
COUNTRIES_WITH_STATE_IN_ADDRESS, PERSON_NAME_SALUTATIONS,
PERSON_NAME_SCHEMES, PERSON_NAME_TITLE_GROUPS,
COUNTRIES_WITH_STATE_IN_ADDRESS, COUNTRY_STATE_LABEL,
PERSON_NAME_SALUTATIONS, PERSON_NAME_SCHEMES, PERSON_NAME_TITLE_GROUPS,
)
from pretix.base.templatetags.rich_text import rich_text
from pretix.base.timemachine import time_machine_now
@@ -127,7 +128,13 @@ class NamePartsWidget(forms.MultiWidget):
if fname == 'title' and self.titles:
widgets.append(Select(attrs=a, choices=[('', '')] + [(d, d) for d in self.titles[1]]))
elif fname == 'salutation':
widgets.append(Select(attrs=a, choices=[('', '---'), ('empty', '')] + PERSON_NAME_SALUTATIONS))
widgets.append(Select(
attrs=a,
choices=[
('', '---'),
('empty', '({})'.format(pgettext_lazy("name_salutation", "not specified"))),
] + PERSON_NAME_SALUTATIONS
))
else:
widgets.append(self.widget(attrs=a))
super().__init__(widgets, attrs)
@@ -245,7 +252,10 @@ class NamePartsFormField(forms.MultiValueField):
d.pop('validators', None)
field = forms.ChoiceField(
**d,
choices=[('', '---'), ('empty', '')] + PERSON_NAME_SALUTATIONS
choices=[
('', '---'),
('empty', '({})'.format(pgettext_lazy("name_salutation", "not specified"))),
] + PERSON_NAME_SALUTATIONS
)
else:
field = forms.CharField(**defaults)
@@ -721,7 +731,7 @@ class BaseQuestionsForm(forms.Form):
'data-country-information-url': reverse('js_helpers.states'),
}),
)
c = [('', pgettext_lazy('address', 'Select state'))]
c = [('', '---')]
fprefix = str(self.prefix) + '-' if self.prefix is not None and self.prefix != '-' else ''
cc = None
state = None
@@ -861,6 +871,23 @@ class BaseQuestionsForm(forms.Form):
attrs['data-min'] = q.valid_date_min.isoformat()
if q.valid_date_max:
attrs['data-max'] = q.valid_date_max.isoformat()
if not help_text:
if q.valid_date_min and q.valid_date_max:
help_text = format_lazy(
'Please enter a date between {min} and {max}.',
min=date_format(q.valid_date_min, "SHORT_DATE_FORMAT"),
max=date_format(q.valid_date_max, "SHORT_DATE_FORMAT"),
)
elif q.valid_date_min:
help_text = format_lazy(
'Please enter a date no earlier than {min}.',
min=date_format(q.valid_date_min, "SHORT_DATE_FORMAT"),
)
elif q.valid_date_max:
help_text = format_lazy(
'Please enter a date no later than {max}.',
max=date_format(q.valid_date_max, "SHORT_DATE_FORMAT"),
)
field = forms.DateField(
label=label, required=required,
help_text=help_text,
@@ -879,6 +906,23 @@ class BaseQuestionsForm(forms.Form):
widget=TimePickerWidget(time_format=get_format_without_seconds('TIME_INPUT_FORMATS')),
)
elif q.type == Question.TYPE_DATETIME:
if not help_text:
if q.valid_datetime_min and q.valid_datetime_max:
help_text = format_lazy(
'Please enter a date and time between {min} and {max}.',
min=date_format(q.valid_datetime_min, "SHORT_DATETIME_FORMAT"),
max=date_format(q.valid_datetime_max, "SHORT_DATETIME_FORMAT"),
)
elif q.valid_datetime_min:
help_text = format_lazy(
'Please enter a date and time no earlier than {min}.',
min=date_format(q.valid_datetime_min, "SHORT_DATETIME_FORMAT"),
)
elif q.valid_datetime_max:
help_text = format_lazy(
'Please enter a date and time no later than {max}.',
max=date_format(q.valid_datetime_max, "SHORT_DATETIME_FORMAT"),
)
field = SplitDateTimeField(
label=label, required=required,
help_text=help_text,
@@ -1079,7 +1123,7 @@ class BaseInvoiceAddressForm(forms.ModelForm):
self.fields['country'].choices = CachedCountries()
self.fields['country'].widget.attrs['data-country-information-url'] = reverse('js_helpers.states')
c = [('', pgettext_lazy('address', 'Select state'))]
c = [('', '---')]
fprefix = self.prefix + '-' if self.prefix else ''
cc = None
if fprefix + 'country' in self.data:
@@ -1088,16 +1132,19 @@ class BaseInvoiceAddressForm(forms.ModelForm):
cc = str(self.initial['country'])
elif self.instance and self.instance.country:
cc = str(self.instance.country)
state_label = pgettext_lazy('address', 'State')
if cc and cc in COUNTRIES_WITH_STATE_IN_ADDRESS:
types, form = COUNTRIES_WITH_STATE_IN_ADDRESS[cc]
statelist = [s for s in pycountry.subdivisions.get(country_code=cc) if s.type in types]
c += sorted([(s.code[3:], s.name) for s in statelist], key=lambda s: s[1])
if cc in COUNTRY_STATE_LABEL:
state_label = COUNTRY_STATE_LABEL[cc]
elif fprefix + 'state' in self.data:
self.data = self.data.copy()
del self.data[fprefix + 'state']
self.fields['state'] = forms.ChoiceField(
label=pgettext_lazy('address', 'State'),
label=state_label,
required=False,
choices=c,
widget=forms.Select(attrs={
@@ -0,0 +1,41 @@
# Generated by Django 4.2.16 on 2025-02-28 13:25
from django.db import migrations, models
def remove_duplicates(apps, schema_editor):
UserKnownLoginSource = apps.get_model("pretixbase", "UserKnownLoginSource")
unique_fields = ["user", "agent_type", "device_type", "os_type", "country"]
duplicates = (
UserKnownLoginSource.objects
.values(*unique_fields)
.order_by()
.annotate(latest_id=models.Max('id'), count=models.Count('id'))
.filter(count__gt=1)
)
for duplicate in duplicates:
(
UserKnownLoginSource.objects
.filter(**{x: duplicate[x] for x in unique_fields})
.exclude(id=duplicate["latest_id"])
.delete()
)
class Migration(migrations.Migration):
dependencies = [
("pretixbase", "0277_customerssoclient_require_pkce_and_more"),
]
operations = [
migrations.RunPython(remove_duplicates, migrations.RunPython.noop),
migrations.AlterUniqueTogether(
name="userknownloginsource",
unique_together={
("user", "agent_type", "device_type", "os_type", "country")
},
),
]
@@ -0,0 +1,23 @@
# Generated by Django 4.2.19 on 2025-03-18 09:12
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('pretixbase', '0278_login_source_add_unique_together'),
]
operations = [
migrations.AddField(
model_name='discount',
name='subevent_date_from',
field=models.DateTimeField(blank=True, null=True),
),
migrations.AddField(
model_name='discount',
name='subevent_date_until',
field=models.DateTimeField(blank=True, null=True),
),
]
+3
View File
@@ -602,6 +602,9 @@ class UserKnownLoginSource(models.Model):
country = FastCountryField(null=True, blank=True)
last_seen = models.DateTimeField()
class Meta:
unique_together = ('user', 'agent_type', 'device_type', 'os_type', 'country')
class StaffSession(models.Model):
user = models.ForeignKey('User', on_delete=models.PROTECT)
+21 -3
View File
@@ -36,7 +36,9 @@ from django_scopes import ScopedManager
from pretix.base.decimal import round_decimal
from pretix.base.models.base import LoggedModel
PositionInfo = namedtuple('PositionInfo', ['item_id', 'subevent_id', 'line_price_gross', 'is_addon_to', 'voucher_discount'])
PositionInfo = namedtuple('PositionInfo',
['item_id', 'subevent_id', 'subevent_date_from', 'line_price_gross', 'is_addon_to',
'voucher_discount'])
class Discount(LoggedModel):
@@ -171,6 +173,17 @@ class Discount(LoggedModel):
"access to sold-out quota will still receive the discount."),
)
subevent_date_from = models.DateTimeField(
verbose_name=pgettext_lazy("subevent", "Available for dates starting from"),
null=True,
blank=True,
)
subevent_date_until = models.DateTimeField(
verbose_name=pgettext_lazy("subevent", "Available for dates starting until"),
null=True,
blank=True,
)
# more feature ideas:
# - max_usages_per_order
# - promote_to_user_if_almost_satisfied
@@ -355,11 +368,15 @@ class Discount(LoggedModel):
# First, filter out everything not even covered by our product scope
condition_candidates = [
idx
for idx, (item_id, subevent_id, line_price_gross, is_addon_to, voucher_discount) in positions.items()
for idx, (item_id, subevent_id, subevent_date_from, line_price_gross, is_addon_to, voucher_discount) in
positions.items()
if (
(self.condition_all_products or item_id in limit_products) and
(self.condition_apply_to_addons or not is_addon_to) and
(not self.condition_ignore_voucher_discounted or voucher_discount is None or voucher_discount == Decimal('0.00'))
and (not subevent_id or (
self.subevent_date_from is None or subevent_date_from >= self.subevent_date_from)) and (
self.subevent_date_until is None or subevent_date_from <= self.subevent_date_until)
)
]
@@ -369,7 +386,8 @@ class Discount(LoggedModel):
benefit_products = {p.pk for p in self.benefit_limit_products.all()}
benefit_candidates = [
idx
for idx, (item_id, subevent_id, line_price_gross, is_addon_to, voucher_discount) in positions.items()
for idx, (item_id, subevent_id, subevent_date_from, line_price_gross, is_addon_to, voucher_discount) in
positions.items()
if (
item_id in benefit_products and
(self.benefit_apply_to_addons or not is_addon_to) and
+38 -25
View File
@@ -60,6 +60,7 @@ from django.urls import reverse
from django.utils.crypto import get_random_string
from django.utils.formats import date_format
from django.utils.functional import cached_property
from django.utils.html import format_html
from django.utils.timezone import make_aware, now
from django.utils.translation import gettext, gettext_lazy as _
from django_scopes import ScopedManager, scopes_disabled
@@ -171,7 +172,7 @@ class EventMixin:
self.date_to.astimezone(tz), ("D" if short else "l")
)
def get_date_range_display(self, tz=None, force_show_end=False, as_html=False) -> str:
def get_date_range_display(self, tz=None, force_show_end=False, as_html=False, try_to_show_times=False) -> str:
"""
Returns a formatted string containing the start date and the end date
of the event with respect to the current locale and to the ``show_date_to``
@@ -180,36 +181,48 @@ class EventMixin:
tz = tz or self.timezone
if (not self.settings.show_date_to and not force_show_end) or not self.date_to:
df, dt = self.date_from, self.date_from
show_times = try_to_show_times
else:
df, dt = self.date_from, self.date_to
return daterange(df.astimezone(tz), dt.astimezone(tz), as_html)
show_times = try_to_show_times and self.settings.show_times and (
# Show times if start and end are on the same day ("08:00-10:00")
dt.astimezone(tz).date() == df.astimezone(tz).date() or
# Show times if start and end are on consecutive days and less than 24h ("23:00-03:00")
(dt.astimezone(tz).date() == df.astimezone(tz).date() + timedelta(days=1) and
dt.astimezone(tz).time() < df.astimezone(tz).time())
)
d = daterange(df.astimezone(tz), dt.astimezone(tz), as_html)
if show_times:
if (not self.settings.show_date_to and not force_show_end) or not self.date_to:
time_str = _date(self.date_from.astimezone(tz), "TIME_FORMAT")
else:
time_str = '{}{}'.format(
_date(self.date_from.astimezone(tz), "TIME_FORMAT"),
_date(self.date_to.astimezone(tz), "TIME_FORMAT"),
)
if as_html:
d = format_html(
d + ' <time datetime="{}" data-timezone="{}" data-time-short>{}</time>',
self.date_from.isoformat(),
str(self.timezone),
time_str,
)
else:
d = d + ' ' + time_str
return d
def get_date_range_display_with_times(self) -> str: # Helper for usage from templates
return self.get_date_range_display(try_to_show_times=True)
def get_date_range_display_with_times_as_html(self) -> str: # Helper for usage from templates
return self.get_date_range_display(try_to_show_times=True, as_html=True)
def get_date_range_display_as_html(self, tz=None, force_show_end=False) -> str:
return self.get_date_range_display(tz, force_show_end, as_html=True)
def get_time_range_display(self, tz=None, force_show_end=False) -> str:
"""
Returns a formatted string containing the start time and sometimes the end time
of the event with respect to the current locale and to the ``show_date_to``
setting. Dates are not shown. This is usually used in combination with get_date_range_display
"""
tz = tz or self.timezone
show_date_to = self.date_to and (self.settings.show_date_to or force_show_end) and (
# Show date to if start and end are on the same day ("08:00-10:00")
self.date_to.astimezone(tz).date() == self.date_from.astimezone(tz).date() or
# Show date to if start and end are on consecutive days and less than 24h ("23:00-03:00")
(self.date_to.astimezone(tz).date() == self.date_from.astimezone(tz).date() + timedelta(days=1) and
self.date_to.astimezone(tz).time() < self.date_from.astimezone(tz).time())
# Do not show end time if this is a 5-day event because there's no way to make it understandable
)
if show_date_to:
return '{} {}'.format(
_date(self.date_from.astimezone(tz), "TIME_FORMAT"),
_date(self.date_to.astimezone(tz), "TIME_FORMAT"),
)
return _date(self.date_from.astimezone(tz), "TIME_FORMAT")
@property
def timezone(self):
return pytz_deprecation_shim.timezone(self.settings.timezone)
+13 -3
View File
@@ -821,7 +821,8 @@ class Item(LoggedModel):
def ask_attendee_data(self):
return self.admission and self.personalized
def tax(self, price=None, base_price_is='auto', currency=None, invoice_address=None, override_tax_rate=None, include_bundled=False):
def tax(self, price=None, base_price_is='auto', currency=None, invoice_address=None, override_tax_rate=None,
include_bundled=False, force_fixed_gross_price=False):
price = price if price is not None else self.default_price
bundled_sum = Decimal('0.00')
@@ -850,7 +851,7 @@ class Item(LoggedModel):
else:
t = self.tax_rule.tax(price, base_price_is=base_price_is, invoice_address=invoice_address,
override_tax_rate=override_tax_rate, currency=currency or self.event.currency,
subtract_from_gross=bundled_sum)
subtract_from_gross=bundled_sum, force_fixed_gross_price=force_fixed_gross_price)
if bundled_sum:
t.name = "MIXED!"
@@ -1836,7 +1837,7 @@ class Question(LoggedModel):
))
llen = len(answer.split(','))
elif all(isinstance(o, QuestionOption) for o in answer):
return o
return answer
else:
l_ = list(self.options.filter(
Q(pk__in=[a for a in answer if isinstance(a, int) or a.isdigit()]) |
@@ -1915,6 +1916,15 @@ class Question(LoggedModel):
if event != item.event:
raise ValidationError(_('One or more items do not belong to this event.'))
def clean(self):
if self.valid_date_max and self.valid_date_min and self.valid_date_min > self.valid_date_max:
raise ValidationError(_("The maximum date must not be before the minimum value."))
if self.valid_datetime_max and self.valid_datetime_min and self.valid_datetime_min > self.valid_datetime_max:
raise ValidationError(_("The maximum date must not be before the minimum value."))
if self.valid_number_max and self.valid_number_min and self.valid_number_min > self.valid_number_max:
raise ValidationError(_("The maximum value must not be lower than the minimum value."))
super().clean()
class QuestionOption(models.Model):
question = models.ForeignKey('Question', related_name='options', on_delete=models.CASCADE)
+4
View File
@@ -1199,6 +1199,8 @@ class Order(LockModel, LoggedModel):
'invoices': [i.pk for i in invoices] if invoices else [],
'attach_tickets': attach_tickets,
'attach_ical': attach_ical,
'attach_other_files': attach_other_files,
'attach_cached_files': [cf.filename for cf in attach_cached_files] if attach_cached_files else [],
}
)
@@ -2857,6 +2859,8 @@ class OrderPosition(AbstractPosition):
'invoices': [i.pk for i in invoices] if invoices else [],
'attach_tickets': attach_tickets,
'attach_ical': attach_ical,
'attach_other_files': attach_other_files,
'attach_cached_files': [],
}
)
+2
View File
@@ -286,6 +286,8 @@ class WaitingListEntry(LoggedModel):
'subject': subject,
'message': email_content,
'recipient': recipient,
'attach_other_files': attach_other_files,
'attach_cached_files': [cf.filename for cf in attach_cached_files] if attach_cached_files else [],
}
)
+13 -6
View File
@@ -330,18 +330,18 @@ class BasePaymentProvider:
label=_('Enable payment method'),
required=False,
)),
('_availability_date',
RelativeDateField(
label=_('Available until'),
help_text=_('Users will not be able to choose this payment provider after the given date.'),
required=False,
)),
('_availability_start',
RelativeDateField(
label=_('Available from'),
help_text=_('Users will not be able to choose this payment provider before the given date.'),
required=False,
)),
('_availability_date',
RelativeDateField(
label=_('Available until'),
help_text=_('Users will not be able to choose this payment provider after the given date.'),
required=False,
)),
('_total_min',
forms.DecimalField(
label=_('Minimum order total'),
@@ -1308,6 +1308,9 @@ class OffsettingProvider(BasePaymentProvider):
def payment_control_render(self, request: HttpRequest, payment: OrderPayment) -> str:
return _('Balanced against orders: %s' % ', '.join(payment.info_data['orders']))
def refund_control_render(self, request: HttpRequest, payment: OrderPayment) -> str:
return self.payment_control_render(request, payment)
class GiftCardPayment(BasePaymentProvider):
identifier = "giftcard"
@@ -1460,6 +1463,10 @@ class GiftCardPayment(BasePaymentProvider):
messages.error(request, _("You cannot pay with gift cards when buying a gift card."))
return
if not request.POST.get("giftcard"):
messages.error(request, _("Please enter the code of your gift card."))
return
try:
gc = self.event.organizer.accepted_gift_cards.get(
secret=request.POST.get("giftcard").strip()
+2 -1
View File
@@ -1398,7 +1398,8 @@ class CartManager:
self.event,
self._sales_channel.identifier,
[
(cp.item_id, cp.subevent_id, cp.line_price_gross, bool(cp.addon_to), cp.is_bundled, cp.listed_price - cp.price_after_voucher)
(cp.item_id, cp.subevent_id, cp.subevent.date_from if cp.subevent_id else None, cp.line_price_gross,
bool(cp.addon_to), cp.is_bundled, cp.listed_price - cp.price_after_voucher)
for cp in positions
]
)
+2 -1
View File
@@ -120,7 +120,8 @@ class CrossSellingService:
self.event,
self.sales_channel,
[
(cp.item_id, cp.subevent_id, cp.line_price_gross, bool(cp.addon_to), cp.is_bundled,
(cp.item_id, cp.subevent_id, cp.subevent.date_from if cp.subevent_id else None, cp.line_price_gross,
bool(cp.addon_to), cp.is_bundled,
cp.listed_price - cp.price_after_voucher)
for cp in self.cartpositions
],
+176 -132
View File
@@ -98,8 +98,9 @@ from pretix.base.services.quotas import QuotaAvailability
from pretix.base.services.tasks import ProfiledEventTask, ProfiledTask
from pretix.base.signals import (
order_approved, order_canceled, order_changed, order_denied, order_expired,
order_fee_calculation, order_paid, order_placed, order_reactivated,
order_split, order_valid_if_pending, periodic_task, validate_order,
order_expiry_changed, order_fee_calculation, order_paid, order_placed,
order_reactivated, order_split, order_valid_if_pending, periodic_task,
validate_order,
)
from pretix.base.timemachine import time_machine_now, time_machine_now_assigned
from pretix.celery_app import app
@@ -302,6 +303,7 @@ def extend_order(order: Order, new_date: datetime, force: bool=False, valid_if_p
'state_change': was_expired
}
)
order_expiry_changed.send(sender=order.event, order=order)
if was_expired:
num_invoices = order.invoices.filter(is_cancellation=False).count()
@@ -873,7 +875,8 @@ def _check_positions(event: Event, now_dt: datetime, time_machine_now_dt: dateti
event,
sales_channel.identifier,
[
(cp.item_id, cp.subevent_id, cp.line_price_gross, bool(cp.addon_to), cp.is_bundled, cp.listed_price - cp.price_after_voucher)
(cp.item_id, cp.subevent_id, cp.subevent.date_from if cp.subevent_id else None, cp.line_price_gross,
bool(cp.addon_to), cp.is_bundled, cp.listed_price - cp.price_after_voucher)
for cp in sorted_positions
]
)
@@ -1561,6 +1564,7 @@ class OrderChangeManager:
AddFeeOperation = namedtuple('AddFeeOperation', ('fee', 'price_diff'))
CancelFeeOperation = namedtuple('CancelFeeOperation', ('fee', 'price_diff'))
RegenerateSecretOperation = namedtuple('RegenerateSecretOperation', ('position',))
ChangeSecretOperation = namedtuple('ChangeSecretOperation', ('position', 'new_secret'))
ChangeValidFromOperation = namedtuple('ChangeValidFromOperation', ('position', 'valid_from'))
ChangeValidUntilOperation = namedtuple('ChangeValidUntilOperation', ('position', 'valid_until'))
AddBlockOperation = namedtuple('AddBlockOperation', ('position', 'block_name', 'ignore_from_quota_while_blocked'))
@@ -1668,6 +1672,9 @@ class OrderChangeManager:
def regenerate_secret(self, position: OrderPosition):
self._operations.append(self.RegenerateSecretOperation(position))
def change_ticket_secret(self, position: OrderPosition, new_secret: str):
self._operations.append(self.ChangeSecretOperation(position, new_secret))
def change_valid_from(self, position: OrderPosition, new_value: datetime):
self._operations.append(self.ChangeValidFromOperation(position, new_value))
@@ -1682,7 +1689,8 @@ class OrderChangeManager:
def change_price(self, position: OrderPosition, price: Decimal):
tax_rule = self._current_tax_rules().get(position.pk, position.tax_rule) or TaxRule.zero()
price = tax_rule.tax(price, base_price_is='gross')
price = tax_rule.tax(price, base_price_is='gross', invoice_address=self._invoice_address,
force_fixed_gross_price=True)
if position.issued_gift_cards.exists():
raise OrderError(self.error_messages['gift_card_change'])
@@ -1747,7 +1755,8 @@ class OrderChangeManager:
self._operations.append(self.AddFeeOperation(fee, fee.value))
def change_fee(self, fee: OrderFee, value: Decimal):
value = (fee.tax_rule or TaxRule.zero()).tax(value, base_price_is='gross')
value = (fee.tax_rule or TaxRule.zero()).tax(value, base_price_is='gross', invoice_address=self._invoice_address,
force_fixed_gross_price=True)
self._totaldiff += value.gross - fee.value
self._invoice_dirty = True
self._operations.append(self.FeeValueOperation(fee, value, value.gross - fee.value))
@@ -1782,7 +1791,8 @@ class OrderChangeManager:
if price is None:
price = get_price(item, variation, subevent=subevent, invoice_address=self._invoice_address)
elif not isinstance(price, TaxedPrice):
price = item.tax(price, base_price_is='gross', invoice_address=self._invoice_address)
price = item.tax(price, base_price_is='gross', invoice_address=self._invoice_address,
force_fixed_gross_price=True)
except TaxRule.SaleNotAllowed:
raise OrderError(self.error_messages['tax_rule_country_blocked'])
@@ -2211,73 +2221,79 @@ class OrderChangeManager:
nextposid = self.order.all_positions.aggregate(m=Max('positionid'))['m'] + 1
split_positions = []
secret_dirty = set()
position_cache = {}
fee_cache = {}
for op in self._operations:
if isinstance(op, self.ItemOperation):
position = position_cache.setdefault(op.position.pk, op.position)
self.order.log_action('pretix.event.order.changed.item', user=self.user, auth=self.auth, data={
'position': op.position.pk,
'positionid': op.position.positionid,
'old_item': op.position.item.pk,
'old_variation': op.position.variation.pk if op.position.variation else None,
'position': position.pk,
'positionid': position.positionid,
'old_item': position.item.pk,
'old_variation': position.variation.pk if position.variation else None,
'new_item': op.item.pk,
'new_variation': op.variation.pk if op.variation else None,
'old_price': op.position.price,
'addon_to': op.position.addon_to_id,
'new_price': op.position.price
'old_price': position.price,
'addon_to': position.addon_to_id,
'new_price': position.price
})
op.position.item = op.item
op.position.variation = op.variation
op.position._calculate_tax()
position.item = op.item
position.variation = op.variation
position._calculate_tax()
if op.position.voucher_budget_use is not None and op.position.voucher and not op.position.addon_to_id:
listed_price = get_listed_price(op.position.item, op.position.variation, op.position.subevent)
if not op.position.item.tax_rule or op.position.item.tax_rule.price_includes_tax:
price_after_voucher = max(op.position.price, op.position.voucher.calculate_price(listed_price))
if position.voucher_budget_use is not None and position.voucher and not position.addon_to_id:
listed_price = get_listed_price(position.item, position.variation, position.subevent)
if not position.item.tax_rule or position.item.tax_rule.price_includes_tax:
price_after_voucher = max(position.price, position.voucher.calculate_price(listed_price))
else:
price_after_voucher = max(op.position.price - op.position.tax_value, op.position.voucher.calculate_price(listed_price))
op.position.voucher_budget_use = max(listed_price - price_after_voucher, Decimal('0.00'))
secret_dirty.add(op.position)
op.position.save()
price_after_voucher = max(position.price - position.tax_value, position.voucher.calculate_price(listed_price))
position.voucher_budget_use = max(listed_price - price_after_voucher, Decimal('0.00'))
secret_dirty.add(position)
position.save()
elif isinstance(op, self.MembershipOperation):
position = position_cache.setdefault(op.position.pk, op.position)
self.order.log_action('pretix.event.order.changed.membership', user=self.user, auth=self.auth, data={
'position': op.position.pk,
'positionid': op.position.positionid,
'old_membership_id': op.position.used_membership_id,
'position': position.pk,
'positionid': position.positionid,
'old_membership_id': position.used_membership_id,
'new_membership_id': op.membership.pk if op.membership else None,
})
op.position.used_membership = op.membership
op.position.save()
position.used_membership = op.membership
position.save()
elif isinstance(op, self.SeatOperation):
position = position_cache.setdefault(op.position.pk, op.position)
self.order.log_action('pretix.event.order.changed.seat', user=self.user, auth=self.auth, data={
'position': op.position.pk,
'positionid': op.position.positionid,
'old_seat': op.position.seat.name if op.position.seat else "-",
'position': position.pk,
'positionid': position.positionid,
'old_seat': position.seat.name if position.seat else "-",
'new_seat': op.seat.name if op.seat else "-",
'old_seat_id': op.position.seat.pk if op.position.seat else None,
'old_seat_id': position.seat.pk if position.seat else None,
'new_seat_id': op.seat.pk if op.seat else None,
})
op.position.seat = op.seat
secret_dirty.add(op.position)
op.position.save()
position.seat = op.seat
secret_dirty.add(position)
position.save()
elif isinstance(op, self.SubeventOperation):
position = position_cache.setdefault(op.position.pk, op.position)
self.order.log_action('pretix.event.order.changed.subevent', user=self.user, auth=self.auth, data={
'position': op.position.pk,
'positionid': op.position.positionid,
'old_subevent': op.position.subevent.pk,
'position': position.pk,
'positionid': position.positionid,
'old_subevent': position.subevent.pk,
'new_subevent': op.subevent.pk,
'old_price': op.position.price,
'new_price': op.position.price
'old_price': position.price,
'new_price': position.price
})
op.position.subevent = op.subevent
secret_dirty.add(op.position)
if op.position.voucher_budget_use is not None and op.position.voucher and not op.position.addon_to_id:
listed_price = get_listed_price(op.position.item, op.position.variation, op.position.subevent)
if not op.position.item.tax_rule or op.position.item.tax_rule.price_includes_tax:
price_after_voucher = max(op.position.price, op.position.voucher.calculate_price(listed_price))
position.subevent = op.subevent
secret_dirty.add(position)
if position.voucher_budget_use is not None and position.voucher and not position.addon_to_id:
listed_price = get_listed_price(position.item, position.variation, position.subevent)
if not position.item.tax_rule or position.item.tax_rule.price_includes_tax:
price_after_voucher = max(position.price, position.voucher.calculate_price(listed_price))
else:
price_after_voucher = max(op.position.price - op.position.tax_value, op.position.voucher.calculate_price(listed_price))
op.position.voucher_budget_use = max(listed_price - price_after_voucher, Decimal('0.00'))
op.position.save()
price_after_voucher = max(position.price - position.tax_value, position.voucher.calculate_price(listed_price))
position.voucher_budget_use = max(listed_price - price_after_voucher, Decimal('0.00'))
position.save()
elif isinstance(op, self.AddFeeOperation):
self.order.log_action('pretix.event.order.changed.addfee', user=self.user, auth=self.auth, data={
'fee': op.fee.pk,
@@ -2286,70 +2302,79 @@ class OrderChangeManager:
op.fee._calculate_tax()
op.fee.save()
elif isinstance(op, self.FeeValueOperation):
fee = fee_cache.setdefault(op.fee.pk, op.fee)
self.order.log_action('pretix.event.order.changed.feevalue', user=self.user, auth=self.auth, data={
'fee': op.fee.pk,
'old_price': op.fee.value,
'fee': fee.pk,
'old_price': fee.value,
'new_price': op.value.gross
})
op.fee.value = op.value.gross
op.fee._calculate_tax()
op.fee.save()
fee.value = op.value.gross
fee._calculate_tax()
fee.save()
elif isinstance(op, self.PriceOperation):
position = position_cache.setdefault(op.position.pk, op.position)
self.order.log_action('pretix.event.order.changed.price', user=self.user, auth=self.auth, data={
'position': op.position.pk,
'positionid': op.position.positionid,
'old_price': op.position.price,
'addon_to': op.position.addon_to_id,
'position': position.pk,
'positionid': position.positionid,
'old_price': position.price,
'addon_to': position.addon_to_id,
'new_price': op.price.gross
})
op.position.price = op.price.gross
op.position.tax_rate = op.price.rate
op.position.tax_value = op.price.tax
op.position.tax_code = op.price.code
op.position.save()
position.price = op.price.gross
position.tax_rate = op.price.rate
position.tax_value = op.price.tax
position.tax_code = op.price.code
position.save(update_fields=['price', 'tax_rate', 'tax_value', 'tax_code'])
elif isinstance(op, self.TaxRuleOperation):
if isinstance(op.position, OrderPosition):
position = position_cache.setdefault(op.position.pk, op.position)
self.order.log_action('pretix.event.order.changed.tax_rule', user=self.user, auth=self.auth, data={
'position': op.position.pk,
'positionid': op.position.positionid,
'addon_to': op.position.addon_to_id,
'old_taxrule': op.position.tax_rule.pk if op.position.tax_rule else None,
'position': position.pk,
'positionid': position.positionid,
'addon_to': position.addon_to_id,
'old_taxrule': position.tax_rule.pk if position.tax_rule else None,
'new_taxrule': op.tax_rule.pk
})
position._calculate_tax(op.tax_rule)
position.save()
elif isinstance(op.position, OrderFee):
fee = fee_cache.setdefault(op.position.pk, op.position)
self.order.log_action('pretix.event.order.changed.tax_rule', user=self.user, auth=self.auth, data={
'fee': op.position.pk,
'fee_type': op.position.fee_type,
'old_taxrule': op.position.tax_rule.pk if op.position.tax_rule else None,
'fee': fee.pk,
'fee_type': fee.fee_type,
'old_taxrule': fee.tax_rule.pk if fee.tax_rule else None,
'new_taxrule': op.tax_rule.pk
})
op.position._calculate_tax(op.tax_rule)
op.position.save()
fee._calculate_tax(op.tax_rule)
fee.save()
elif isinstance(op, self.CancelFeeOperation):
fee = fee_cache.setdefault(op.fee.pk, op.fee)
self.order.log_action('pretix.event.order.changed.cancelfee', user=self.user, auth=self.auth, data={
'fee': op.fee.pk,
'fee_type': op.fee.fee_type,
'old_price': op.fee.value,
'fee': fee.pk,
'fee_type': fee.fee_type,
'old_price': fee.value,
})
op.fee.canceled = True
op.fee.save(update_fields=['canceled'])
fee.canceled = True
fee.save(update_fields=['canceled'])
elif isinstance(op, self.CancelOperation):
for gc in op.position.issued_gift_cards.all():
position = position_cache.setdefault(op.position.pk, op.position)
for gc in position.issued_gift_cards.all():
gc = GiftCard.objects.select_for_update(of=OF_SELF).get(pk=gc.pk)
if gc.value < op.position.price:
if gc.value < position.price:
raise OrderError(_(
'A position can not be canceled since the gift card {card} purchased in this order has '
'already been redeemed.').format(
card=gc.secret
))
else:
gc.transactions.create(value=-op.position.price, order=self.order, acceptor=self.order.event.organizer)
gc.transactions.create(value=-position.price, order=self.order, acceptor=self.order.event.organizer)
for m in op.position.granted_memberships.with_usages().all():
for m in position.granted_memberships.with_usages().all():
m.canceled = True
m.save()
for opa in op.position.addons.all():
for opa in position.addons.all():
opa = position_cache.setdefault(opa.pk, opa)
for gc in opa.issued_gift_cards.all():
gc = GiftCard.objects.select_for_update(of=OF_SELF).get(pk=gc.pk)
if gc.value < opa.position.price:
@@ -2383,22 +2408,22 @@ class OrderChangeManager:
)
opa.save(update_fields=['canceled', 'secret'])
self.order.log_action('pretix.event.order.changed.cancel', user=self.user, auth=self.auth, data={
'position': op.position.pk,
'positionid': op.position.positionid,
'old_item': op.position.item.pk,
'old_variation': op.position.variation.pk if op.position.variation else None,
'old_price': op.position.price,
'position': position.pk,
'positionid': position.positionid,
'old_item': position.item.pk,
'old_variation': position.variation.pk if position.variation else None,
'old_price': position.price,
'addon_to': None,
})
op.position.canceled = True
if op.position.voucher:
Voucher.objects.filter(pk=op.position.voucher.pk).update(redeemed=Greatest(0, F('redeemed') - 1))
position.canceled = True
if position.voucher:
Voucher.objects.filter(pk=position.voucher.pk).update(redeemed=Greatest(0, F('redeemed') - 1))
assign_ticket_secret(
event=self.event, position=op.position, force_invalidate_if_revokation_list_used=True, force_invalidate=False, save=False
event=self.event, position=position, force_invalidate_if_revokation_list_used=True, force_invalidate=False, save=False
)
if op.position in secret_dirty:
secret_dirty.remove(op.position)
op.position.save(update_fields=['canceled', 'secret'])
if position in secret_dirty:
secret_dirty.remove(position)
position.save(update_fields=['canceled', 'secret'])
elif isinstance(op, self.AddOperation):
pos = OrderPosition.objects.create(
item=op.item, variation=op.variation, addon_to=op.addon_to,
@@ -2423,13 +2448,28 @@ class OrderChangeManager:
'valid_until': op.valid_until.isoformat() if op.valid_until else None,
})
elif isinstance(op, self.SplitOperation):
split_positions.append(op.position)
position = position_cache.setdefault(op.position.pk, op.position)
split_positions.append(position)
elif isinstance(op, self.RegenerateSecretOperation):
op.position.web_secret = generate_secret()
op.position.save(update_fields=["web_secret"])
position = position_cache.setdefault(op.position.pk, op.position)
position.web_secret = generate_secret()
position.save(update_fields=["web_secret"])
assign_ticket_secret(
event=self.event, position=op.position, force_invalidate=True, save=True
event=self.event, position=position, force_invalidate=True, save=True
)
if position in secret_dirty:
secret_dirty.remove(position)
tickets.invalidate_cache.apply_async(kwargs={'event': self.event.pk,
'order': self.order.pk})
self.order.log_action('pretix.event.order.changed.secret', user=self.user, auth=self.auth, data={
'position': position.pk,
'positionid': position.positionid,
})
elif isinstance(op, self.ChangeSecretOperation):
if OrderPosition.all.filter(order__event=self.event, secret=op.new_secret).exists():
raise OrderError('You cannot assign a position secret that already exists.')
op.position.secret = op.new_secret
op.position.save(update_fields=["secret"])
if op.position in secret_dirty:
secret_dirty.remove(op.position)
tickets.invalidate_cache.apply_async(kwargs={'event': self.event.pk,
@@ -2439,64 +2479,68 @@ class OrderChangeManager:
'positionid': op.position.positionid,
})
elif isinstance(op, self.ChangeValidFromOperation):
position = position_cache.setdefault(op.position.pk, op.position)
self.order.log_action('pretix.event.order.changed.valid_from', user=self.user, auth=self.auth, data={
'position': op.position.pk,
'positionid': op.position.positionid,
'position': position.pk,
'positionid': position.positionid,
'new_value': op.valid_from.isoformat() if op.valid_from else None,
'old_value': op.position.valid_from.isoformat() if op.position.valid_from else None,
'old_value': position.valid_from.isoformat() if position.valid_from else None,
})
op.position.valid_from = op.valid_from
op.position.save(update_fields=['valid_from'])
secret_dirty.add(op.position)
position.valid_from = op.valid_from
position.save(update_fields=['valid_from'])
secret_dirty.add(position)
elif isinstance(op, self.ChangeValidUntilOperation):
position = position_cache.setdefault(op.position.pk, op.position)
self.order.log_action('pretix.event.order.changed.valid_until', user=self.user, auth=self.auth, data={
'position': op.position.pk,
'positionid': op.position.positionid,
'position': position.pk,
'positionid': position.positionid,
'new_value': op.valid_until.isoformat() if op.valid_until else None,
'old_value': op.position.valid_until.isoformat() if op.position.valid_until else None,
'old_value': position.valid_until.isoformat() if position.valid_until else None,
})
op.position.valid_until = op.valid_until
op.position.save(update_fields=['valid_until'])
secret_dirty.add(op.position)
position.valid_until = op.valid_until
position.save(update_fields=['valid_until'])
secret_dirty.add(position)
elif isinstance(op, self.AddBlockOperation):
position = position_cache.setdefault(op.position.pk, op.position)
self.order.log_action('pretix.event.order.changed.add_block', user=self.user, auth=self.auth, data={
'position': op.position.pk,
'positionid': op.position.positionid,
'position': position.pk,
'positionid': position.positionid,
'block_name': op.block_name,
})
if op.position.blocked:
if op.block_name not in op.position.blocked:
op.position.blocked = op.position.blocked + [op.block_name]
if position.blocked:
if op.block_name not in position.blocked:
position.blocked = position.blocked + [op.block_name]
else:
op.position.blocked = [op.block_name]
position.blocked = [op.block_name]
if op.ignore_from_quota_while_blocked is not None:
op.position.ignore_from_quota_while_blocked = op.ignore_from_quota_while_blocked
op.position.save(update_fields=['blocked', 'ignore_from_quota_while_blocked'])
if op.position.blocked:
op.position.blocked_secrets.update_or_create(
position.ignore_from_quota_while_blocked = op.ignore_from_quota_while_blocked
position.save(update_fields=['blocked', 'ignore_from_quota_while_blocked'])
if position.blocked:
position.blocked_secrets.update_or_create(
event=self.event,
secret=op.position.secret,
secret=position.secret,
defaults={
'blocked': True,
'updated': now(),
}
)
elif isinstance(op, self.RemoveBlockOperation):
position = position_cache.setdefault(op.position.pk, op.position)
self.order.log_action('pretix.event.order.changed.remove_block', user=self.user, auth=self.auth, data={
'position': op.position.pk,
'positionid': op.position.positionid,
'position': position.pk,
'positionid': position.positionid,
'block_name': op.block_name,
})
if op.position.blocked and op.block_name in op.position.blocked:
op.position.blocked = [b for b in op.position.blocked if b != op.block_name]
if not op.position.blocked:
op.position.blocked = None
if position.blocked and op.block_name in position.blocked:
position.blocked = [b for b in position.blocked if b != op.block_name]
if not position.blocked:
position.blocked = None
if op.ignore_from_quota_while_blocked is not None:
op.position.ignore_from_quota_while_blocked = op.ignore_from_quota_while_blocked
op.position.save(update_fields=['blocked', 'ignore_from_quota_while_blocked'])
if not op.position.blocked:
position.ignore_from_quota_while_blocked = op.ignore_from_quota_while_blocked
position.save(update_fields=['blocked', 'ignore_from_quota_while_blocked'])
if not position.blocked:
try:
bs = op.position.blocked_secrets.get(secret=op.position.secret)
bs = position.blocked_secrets.get(secret=position.secret)
bs.blocked = False
bs.save()
except BlockedTicketSecret.DoesNotExist:
+8 -5
View File
@@ -21,6 +21,7 @@
#
import re
from collections import defaultdict
from datetime import datetime
from decimal import Decimal
from typing import List, Optional, Tuple, Union
@@ -162,14 +163,14 @@ def get_line_price(price_after_voucher: Decimal, custom_price_input: Decimal, cu
def apply_discounts(event: Event, sales_channel: Union[str, SalesChannel],
positions: List[Tuple[int, Optional[int], Decimal, bool, bool, Decimal]],
positions: List[Tuple[int, Optional[int], Optional[datetime], Decimal, bool, bool, Decimal]],
collect_potential_discounts: Optional[defaultdict]=None) -> List[Tuple[Decimal, Optional[Discount]]]:
"""
Applies any dynamic discounts to a cart
:param event: Event the cart belongs to
:param sales_channel: Sales channel the cart was created with
:param positions: Tuple of the form ``(item_id, subevent_id, line_price_gross, is_addon_to, is_bundled, voucher_discount)``
:param positions: Tuple of the form ``(item_id, subevent_id, subevent_date_from, line_price_gross, is_addon_to, is_bundled, voucher_discount)``
:param collect_potential_discounts: If a `defaultdict(list)` is supplied, all discounts that could be applied to the cart
based on the "consumed" items, but lack matching "benefitting" items will be collected therein.
The dict will contain a mapping from index in the `positions` list of the item that could be consumed, to a list
@@ -191,12 +192,14 @@ def apply_discounts(event: Event, sales_channel: Union[str, SalesChannel],
).prefetch_related('condition_limit_products', 'benefit_limit_products').order_by('position', 'pk')
for discount in discount_qs:
result = discount.apply({
idx: PositionInfo(item_id, subevent_id, line_price_gross, is_addon_to, voucher_discount)
for idx, (item_id, subevent_id, line_price_gross, is_addon_to, is_bundled, voucher_discount) in enumerate(positions)
idx: PositionInfo(item_id, subevent_id, subevent_date_from, line_price_gross, is_addon_to, voucher_discount)
for
idx, (item_id, subevent_id, subevent_date_from, line_price_gross, is_addon_to, is_bundled, voucher_discount)
in enumerate(positions)
if not is_bundled and idx not in new_prices
}, collect_potential_discounts)
for k in result.keys():
result[k] = (result[k], discount)
new_prices.update(result)
return [new_prices.get(idx, (p[2], None)) for idx, p in enumerate(positions)]
return [new_prices.get(idx, (p[3], None)) for idx, p in enumerate(positions)]
+2 -2
View File
@@ -134,13 +134,13 @@ def order_overview(
qs = qs.filter(item__admission=True)
items = items.filter(admission=True)
if date_from and isinstance(date_from, date):
if date_from and isinstance(date_from, date) and not isinstance(date_from, datetime):
date_from = make_aware(datetime.combine(
date_from,
time(hour=0, minute=0, second=0, microsecond=0)
), event.timezone)
if date_until and isinstance(date_until, date):
if date_until and isinstance(date_until, date) and not isinstance(date_until, datetime):
date_until = make_aware(datetime.combine(
date_until + timedelta(days=1),
time(hour=0, minute=0, second=0, microsecond=0)
+17 -5
View File
@@ -2108,7 +2108,7 @@ DEFAULTS = {
'form_class': I18nFormField,
'form_kwargs': dict(
label=_("Event description"),
widget=I18nMarkdownTextarea,
widget=I18nTextarea,
help_text=_(
"You can use this to share information with your attendees, such as travel information or the link to a digital event. "
"If you keep it empty, we will put a link to the event shop, the admission time, and your organizer name in there. "
@@ -2883,7 +2883,8 @@ Your {organizer} team""")) # noqa: W291
ext_whitelist=settings.FILE_UPLOAD_EXTENSIONS_IMAGE,
max_size=settings.FILE_UPLOAD_MAX_SIZE_IMAGE,
help_text=_('If you provide a logo image, we will by default not show your event name and date '
'in the page header. By default, we show your logo with a size of up to 1140x120 pixels. You '
'in the page header. If you use a white background, we show your logo with a size of up '
'to 1140x120 pixels. Otherwise the maximum size is 1120x120 pixels. You '
'can increase the size with the setting below. We recommend not using small details on the picture '
'as it will be resized on smaller screens.')
),
@@ -2926,7 +2927,8 @@ Your {organizer} team""")) # noqa: W291
ext_whitelist=settings.FILE_UPLOAD_EXTENSIONS_IMAGE,
max_size=settings.FILE_UPLOAD_MAX_SIZE_IMAGE,
help_text=_('If you provide a logo image, we will by default not show your organization name '
'in the page header. By default, we show your logo with a size of up to 1140x120 pixels. You '
'in the page header. If you use a white background, we show your logo with a size of up '
'to 1140x120 pixels. Otherwise the maximum size is 1120x120 pixels. You '
'can increase the size with the setting below. We recommend not using small details on the picture '
'as it will be resized on smaller screens.')
),
@@ -2987,7 +2989,7 @@ Your {organizer} team""")) # noqa: W291
help_text=_('This picture will be used as a preview if you post links to your ticket shop on social media. '
'Facebook advises to use a picture size of 1200 x 630 pixels, however some platforms like '
'WhatsApp and Reddit only show a square preview, so we recommend to make sure it still looks good '
'only the center square is shown. If you do not fill this, we will use the logo given above.')
'if only the center square is shown. If you do not fill this, we will use the logo given above.')
),
'serializer_class': UploadedFileField,
'serializer_kwargs': dict(
@@ -3291,6 +3293,8 @@ Your {organizer} team""")) # noqa: W291
label=_('Validity of gift card codes in years'),
help_text=_('If you set a number here, gift cards will by default expire at the end of the year after this '
'many years. If you keep it empty, gift cards do not have an explicit expiry date.'),
min_value=0,
max_value=99,
)
},
'cookie_consent': {
@@ -3703,13 +3707,21 @@ COUNTRIES_WITH_STATE_IN_ADDRESS = {
# are actually *used* in postal addresses. This is obviously not complete and opinionated.
# Country: [(List of subdivision types as defined by pycountry), (short or long form to be used)]
'AU': (['State', 'Territory'], 'short'),
'BR': (['State'], 'short'),
'BR': (['Federal district', 'State'], 'short'),
'CA': (['Province', 'Territory'], 'short'),
# 'CN': (['Province', 'Autonomous region', 'Munincipality'], 'long'),
'JP': (['Prefecture'], 'long'),
'MY': (['State', 'Federal territory'], 'long'),
'MX': (['State', 'Federal district'], 'short'),
'US': (['State', 'Outlying area', 'District'], 'short'),
'IT': (['Province', 'Free municipal consortium', 'Metropolitan city', 'Autonomous province',
'Free municipal consortium', 'Decentralized regional entity'], 'short'),
}
COUNTRY_STATE_LABEL = {
# Countries in which the "State" field should not be called "State"
'CA': pgettext_lazy('address', 'Province'),
'JP': pgettext_lazy('address', 'Prefecture'),
'IT': pgettext_lazy('address', 'Province'),
}
settings_hierarkey = Hierarkey(attribute_name='settings')
+10 -1
View File
@@ -46,7 +46,6 @@ app_cache = {}
def _populate_app_cache():
global app_cache
apps.check_apps_ready()
for ac in apps.app_configs.values():
app_cache[ac.name] = ac
@@ -563,6 +562,16 @@ as the first argument.
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
"""
order_expiry_changed = EventPluginSignal()
"""
Arguments: ``order``
This signal is sent out every time an order expiry date is changed as an explicit operation (i.e. not if
this is the result of an approval or order change). The order object is given as the first argument.
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
"""
order_modified = EventPluginSignal()
"""
Arguments: ``order``
+1 -1
View File
@@ -28,7 +28,7 @@
<code>Host: {{ request.headers.Host }}</code>
{% if xfh %}
<br>
<code>X-Forwarded-For: {{ xfh }}</code>
<code>X-Forwarded-Host: {{ xfh }}</code>
{% if not settings.USE_X_FORWARDED_HOST %}({% trans "ignored" %}){% endif %}
{% endif %}
</dd>
@@ -4,7 +4,7 @@
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=false">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style type="text/css">
body {
background-color: #eee;
@@ -15,10 +15,7 @@
{{ event.name }}
<br>
{% if event.has_subevents and ev.name|upper != event.name|upper %}{{ ev.name }}<br>{% endif %}
{{ ev.get_date_range_display }}
{% if event.settings.show_times %}
{{ ev.date_from|date:"TIME_FORMAT" }}
{% endif %}
{{ ev.get_date_range_display_with_times }}
</td>
</tr>
<tr>
@@ -107,10 +104,7 @@
{% if groupkey.2.name|upper != event.name|upper %}
{{ groupkey.2.name }} &middot;
{% endif %}
{{ groupkey.2.get_date_range_display }}
{% if event.settings.show_times %}
{{ groupkey.2.date_from|date:"TIME_FORMAT" }}
{% endif %}
{{ groupkey.2.get_date_range_display_with_times }}
{% if groupkey.2.location %}
<br>
{{ groupkey.2.location|oneline }}
+9 -2
View File
@@ -21,12 +21,15 @@
#
import pycountry
from django.http import JsonResponse
from django.utils.translation import pgettext
from pretix.base.addressvalidation import (
COUNTRIES_WITH_STREET_ZIPCODE_AND_CITY_REQUIRED,
)
from pretix.base.models.tax import VAT_ID_COUNTRIES
from pretix.base.settings import COUNTRIES_WITH_STATE_IN_ADDRESS
from pretix.base.settings import (
COUNTRIES_WITH_STATE_IN_ADDRESS, COUNTRY_STATE_LABEL,
)
def states(request):
@@ -35,7 +38,11 @@ def states(request):
'street': {'required': True},
'zipcode': {'required': cc in COUNTRIES_WITH_STREET_ZIPCODE_AND_CITY_REQUIRED},
'city': {'required': cc in COUNTRIES_WITH_STREET_ZIPCODE_AND_CITY_REQUIRED},
'state': {'visible': cc in COUNTRIES_WITH_STATE_IN_ADDRESS, 'required': cc in COUNTRIES_WITH_STATE_IN_ADDRESS},
'state': {
'visible': cc in COUNTRIES_WITH_STATE_IN_ADDRESS,
'required': cc in COUNTRIES_WITH_STATE_IN_ADDRESS,
'label': COUNTRY_STATE_LABEL.get(cc, pgettext('address', 'State')),
},
'vat_id': {'visible': cc in VAT_ID_COUNTRIES, 'required': False},
}
if cc not in COUNTRIES_WITH_STATE_IN_ADDRESS:
+4 -3
View File
@@ -43,7 +43,7 @@ from django.utils.translation import get_language
from django_scopes import scope
from pretix.base.models.auth import StaffSession
from pretix.base.settings import GlobalSettingsObject
from pretix.base.settings import COUNTRY_STATE_LABEL, GlobalSettingsObject
from pretix.control.navigation import (
get_event_navigation, get_global_navigation, get_organizer_navigation,
)
@@ -81,13 +81,13 @@ def _default_context(request):
'DEBUG': settings.DEBUG,
}
_html_head = []
if hasattr(request, 'event') and request.user.is_authenticated:
if getattr(request, 'event', None) and request.user.is_authenticated:
for receiver, response in html_head.send(request.event, request=request):
_html_head.append(response)
ctx['html_head'] = "".join(_html_head)
_js_payment_weekdays_disabled = '[]'
if getattr(request, 'event', None) and hasattr(request, 'organizer') and request.user.is_authenticated:
if getattr(request, 'event', None) and getattr(request, 'organizer', None) and request.user.is_authenticated:
ctx['nav_items'] = get_event_navigation(request)
if request.event.settings.get('payment_term_weekdays'):
@@ -140,6 +140,7 @@ def _default_context(request):
ctx['js_time_format'] = get_javascript_format('TIME_INPUT_FORMATS')
ctx['js_locale'] = get_moment_locale()
ctx['select2locale'] = get_language()[:2]
ctx['COUNTRY_STATE_LABEL'] = COUNTRY_STATE_LABEL
ctx['warning_update_available'] = False
ctx['warning_update_check_active'] = False
+6
View File
@@ -45,6 +45,8 @@ class DiscountForm(I18nModelForm):
'limit_sales_channels',
'available_from',
'available_until',
'subevent_date_from',
'subevent_date_until',
'subevent_mode',
'condition_all_products',
'condition_limit_products',
@@ -62,6 +64,8 @@ class DiscountForm(I18nModelForm):
field_classes = {
'available_from': SplitDateTimeField,
'available_until': SplitDateTimeField,
'subevent_date_from': SplitDateTimeField,
'subevent_date_until': SplitDateTimeField,
'condition_limit_products': ItemMultipleChoiceField,
'benefit_limit_products': ItemMultipleChoiceField,
'limit_sales_channels': SafeModelMultipleChoiceField,
@@ -70,6 +74,8 @@ class DiscountForm(I18nModelForm):
'subevent_mode': forms.RadioSelect,
'available_from': SplitDateTimePickerWidget(),
'available_until': SplitDateTimePickerWidget(attrs={'data-date-after': '#id_available_from_0'}),
'subevent_date_from': SplitDateTimePickerWidget(),
'subevent_date_until': SplitDateTimePickerWidget(attrs={'data-date-after': '#id_subevent_date_from_0'}),
'condition_limit_products': forms.CheckboxSelectMultiple(attrs={
'data-inverse-dependency': '<[name$=all_products]',
'class': 'scrolling-multiple-choice',
+3 -1
View File
@@ -1475,7 +1475,9 @@ class CountriesAndEUAndStates(CountriesAndEU):
def __iter__(self):
for country_code, country_name in super().__iter__():
yield country_code, country_name
if country_code in COUNTRIES_WITH_STATE_IN_ADDRESS:
if country_code in COUNTRIES_WITH_STATE_IN_ADDRESS and country_code not in {"IT"}:
# Special case for Italy: Provinces are used in addresses, but are too low-level to
# have influence on taxes, so we avoid the bloat in the list of selectable countries.
types, form = COUNTRIES_WITH_STATE_IN_ADDRESS[country_code]
yield from sorted(((state.code, country_name + " - " + state.name)
for state in pycountry.subdivisions.get(country_code=country_code)
+12 -17
View File
@@ -70,6 +70,7 @@ from pretix.helpers.database import (
)
from pretix.helpers.dicts import move_to_end
from pretix.helpers.i18n import get_format_without_seconds, i18ncomp
from pretix.helpers.models import flatten_choices
PAYMENT_PROVIDERS = []
@@ -177,10 +178,10 @@ class FilterForm(forms.Form):
elif isinstance(v, Model):
val = '"' + str(v) + '"'
elif isinstance(f, forms.MultipleChoiceField):
valdict = dict(f.choices)
valdict = dict(flatten_choices(f.choices))
val = ' or '.join([str(valdict.get(m)) for m in v])
elif isinstance(f, forms.ChoiceField):
val = str(dict(f.choices).get(v))
val = str(dict(flatten_choices(f.choices)).get(v))
elif isinstance(v, datetime):
val = date_format(v, 'SHORT_DATETIME_FORMAT')
elif isinstance(v, Decimal):
@@ -196,7 +197,6 @@ class OrderFilterForm(FilterForm):
label=_('Search for…'),
widget=forms.TextInput(attrs={
'placeholder': _('Search for…'),
'autofocus': 'autofocus'
}),
required=False
)
@@ -267,9 +267,10 @@ class OrderFilterForm(FilterForm):
Q(invoice_no__in=invoice_nos)
| Q(full_invoice_no__iexact=u)
).values_list('order_id', flat=True)
matching_positions = OrderPosition.objects.filter(
matching_positions = OrderPosition.all.filter(
Q(
Q(attendee_name_cached__icontains=u) | Q(attendee_email__icontains=u)
| Q(company__icontains=u)
| Q(secret__istartswith=u)
| Q(pseudonymization_id__istartswith=u)
)
@@ -849,12 +850,18 @@ class EventOrderExpertFilterForm(EventOrderFilterForm):
).distinct()
for q in self.event.questions.all():
if fdata.get(f'question_{q.pk}'):
if q.type == Question.TYPE_BOOLEAN:
if q.type in (Question.TYPE_BOOLEAN, Question.TYPE_NUMBER):
answers = QuestionAnswer.objects.filter(
question_id=q.pk,
orderposition__order_id=OuterRef('pk'),
answer__exact=fdata.get(f'question_{q.pk}')
)
elif q.type in (Question.TYPE_DATE, Question.TYPE_TIME, Question.TYPE_DATETIME):
answers = QuestionAnswer.objects.filter(
question_id=q.pk,
orderposition__order_id=OuterRef('pk'),
answer__exact=str(fdata.get(f'question_{q.pk}'))
)
elif q.type in (Question.TYPE_CHOICE, Question.TYPE_CHOICE_MULTIPLE):
answers = QuestionAnswer.objects.filter(
question_id=q.pk,
@@ -980,7 +987,6 @@ class OrderPaymentSearchFilterForm(forms.Form):
label=_('Search for…'),
widget=forms.TextInput(attrs={
'placeholder': _('Search for…'),
'autofocus': 'autofocus'
}),
required=False,
)
@@ -1242,7 +1248,6 @@ class SubEventFilterForm(FilterForm):
label=_('Event name'),
widget=forms.TextInput(attrs={
'placeholder': _('Event name'),
'autofocus': 'autofocus'
}),
required=False
)
@@ -1375,7 +1380,6 @@ class OrganizerFilterForm(FilterForm):
label=_('Organizer name'),
widget=forms.TextInput(attrs={
'placeholder': _('Organizer name'),
'autofocus': 'autofocus'
}),
required=False
)
@@ -1433,7 +1437,6 @@ class GiftCardFilterForm(FilterForm):
label=_('Search query'),
widget=forms.TextInput(attrs={
'placeholder': _('Search query'),
'autofocus': 'autofocus'
}),
required=False
)
@@ -1485,7 +1488,6 @@ class CustomerFilterForm(FilterForm):
label=_('Search query'),
widget=forms.TextInput(attrs={
'placeholder': _('Search query'),
'autofocus': 'autofocus'
}),
required=False
)
@@ -1558,7 +1560,6 @@ class ReusableMediaFilterForm(FilterForm):
label=_('Search query'),
widget=forms.TextInput(attrs={
'placeholder': _('Search query'),
'autofocus': 'autofocus'
}),
required=False
)
@@ -1613,7 +1614,6 @@ class TeamFilterForm(FilterForm):
label=_('Search query'),
widget=forms.TextInput(attrs={
'placeholder': _('Search query'),
'autofocus': 'autofocus'
}),
required=False
)
@@ -1695,7 +1695,6 @@ class EventFilterForm(FilterForm):
label=_('Event name'),
widget=forms.TextInput(attrs={
'placeholder': _('Event name'),
'autofocus': 'autofocus'
}),
required=False
)
@@ -1878,7 +1877,6 @@ class CheckinListAttendeeFilterForm(FilterForm):
label=_('Search attendee…'),
widget=forms.TextInput(attrs={
'placeholder': _('Search attendee…'),
'autofocus': 'autofocus'
}),
required=False
)
@@ -2027,7 +2025,6 @@ class UserFilterForm(FilterForm):
label=_('Search query'),
widget=forms.TextInput(attrs={
'placeholder': _('Search query'),
'autofocus': 'autofocus'
}),
required=False
)
@@ -2119,7 +2116,6 @@ class VoucherFilterForm(FilterForm):
label=_('Search voucher'),
widget=forms.TextInput(attrs={
'placeholder': _('Search voucher'),
'autofocus': 'autofocus'
}),
required=False
)
@@ -2597,7 +2593,6 @@ class DeviceFilterForm(FilterForm):
label=_('Search query'),
widget=forms.TextInput(attrs={
'placeholder': _('Search query'),
'autofocus': 'autofocus'
}),
required=False
)
+11
View File
@@ -25,6 +25,8 @@ import socket
from django import forms
from django.conf import settings
from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator
from django.utils.text import format_lazy
from django.utils.translation import gettext_lazy as _
from pretix.base.forms import SecretKeySettingsField, SettingsForm
@@ -54,6 +56,15 @@ class SMTPMailForm(SettingsForm):
smtp_password = SecretKeySettingsField(
label=_("Password"),
required=False,
validators=[RegexValidator(
r"^[A-Za-z0-9!\"#$%&'()*+,./:;<=>?@\^_`{}|~-]+$",
message=format_lazy(
_("The password contains characters not supported by our email system. Please only use characters "
"A-Z, a-z, 0-9, and common special characters ({characters})."),
characters=r'!"#$%%&\'()*+,-./:;<=>?@\^_`{}|~'
)
)]
)
smtp_use_tls = forms.BooleanField(
label=_("Use STARTTLS"),
+11
View File
@@ -33,6 +33,7 @@
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under the License.
import os.path
from datetime import date, datetime, time
from decimal import Decimal
@@ -68,6 +69,7 @@ from pretix.base.services.placeholders import FormPlaceholderMixin
from pretix.base.services.pricing import get_price
from pretix.control.forms import SplitDateTimeField
from pretix.control.forms.widgets import Select2
from pretix.helpers.hierarkey import clean_filename
from pretix.helpers.money import change_decimal_field
@@ -723,6 +725,9 @@ class OrderMailForm(forms.Form):
help_text=_("Will be ignored if tickets exceed a given size limit to ensure email deliverability."),
required=False
)
attach_new_order = forms.BooleanField(
required=False
)
attach_invoices = forms.ModelMultipleChoiceField(
label=_("Attach invoices"),
widget=forms.CheckboxSelectMultiple,
@@ -759,6 +764,12 @@ class OrderMailForm(forms.Form):
self.fields['attach_invoices'].queryset = order.invoices.all()
self._set_field_placeholders('message', ['event', 'order'])
self._set_field_placeholders('subject', ['event', 'order'])
if order.event.settings.mail_attachment_new_order:
self.fields['attach_new_order'].label = _('Attach {file}').format(
file=clean_filename(os.path.basename(order.event.settings.mail_attachment_new_order.name))
)
else:
del self.fields['attach_new_order']
class OrderPositionMailForm(OrderMailForm):
+2 -1
View File
@@ -522,7 +522,8 @@ class OrganizerSettingsForm(SettingsForm):
max_size=settings.FILE_UPLOAD_MAX_SIZE_IMAGE,
required=False,
help_text=_('If you provide a logo image, we will by default not show your organization name '
'in the page header. By default, we show your logo with a size of up to 1140x120 pixels. You '
'in the page header. If you use a white background, we show your logo with a size of up '
'to 1140x120 pixels. Otherwise the maximum size is 1120x120 pixels. You '
'can increase the size with the setting below. We recommend not using small details on the picture '
'as it will be resized on smaller screens.')
)
+2 -3
View File
@@ -43,7 +43,6 @@ from django.dispatch import receiver
from django.urls import reverse
from django.utils.formats import date_format
from django.utils.html import escape, format_html
from django.utils.safestring import mark_safe
from django.utils.translation import gettext_lazy as _, pgettext_lazy
from i18nfield.strings import LazyI18nString
@@ -286,7 +285,7 @@ class OrderChangedSplit(OrderChangeLogEntryType):
_('Position #{posid} ({old_item}, {old_price}) split into new order: {order}'),
old_item=escape(old_item),
posid=data.get('positionid', '?'),
order=format_html(mark_safe('<a href="{}">{}</a>'), url, data['new_order']),
order=format_html('<a href="{}">{}</a>', url, data['new_order']),
old_price=money_filter(Decimal(data['old_price']), event.currency),
)
@@ -303,7 +302,7 @@ class OrderChangedSplitFrom(OrderLogEntryType):
})
return format_html(
_('This order has been created by splitting the order {order}'),
order=format_html(mark_safe('<a href="{}">{}</a>'), url, data['original_order']),
order=format_html('<a href="{}">{}</a>', url, data['original_order']),
)
+1 -1
View File
@@ -59,7 +59,7 @@ def get_event_navigation(request: HttpRequest):
'event': request.event.slug,
'organizer': request.event.organizer.slug,
}),
'active': url.url_name == 'event.settings.payment',
'active': url.url_name in ('event.settings.payment', 'event.settings.payment.provider'),
},
{
'label': _('Plugins'),
@@ -13,7 +13,7 @@
{% endfor %}
<p>
{% blocktrans trimmed count count=cnt %}
Are you sure you want to permanently delete the check-ins of <strong>one ticket</strong>.
Are you sure you want to permanently delete the check-ins of <strong>one ticket</strong>?
{% plural %}
Are you sure you want to permanently delete the check-ins of <strong>{{ count }} tickets</strong>?
{% endblocktrans %}
@@ -148,7 +148,7 @@
<td>{{ e.item }}{% if e.variation %} {{ e.variation }}{% endif %}</td>
{% if request.event.has_subevents and not checkinlist.subevent %}
<td>
{{ e.subevent.name }} {{ e.subevent.get_date_range_display }} {{ e.subevent.date_from|date:"TIME_FORMAT" }}
{{ e.subevent.name }} {{ e.subevent.get_date_range_display_with_times }}
</td>
{% endif %}
{% if seats %}
@@ -127,8 +127,7 @@
{% if request.event.has_subevents %}
{% if cl.subevent %}
<td>
{{ cl.subevent.name }} {{ cl.subevent.get_date_range_display }}
{{ cl.subevent.date_from|date:"TIME_FORMAT" }}
{{ cl.subevent.name }} {{ cl.subevent.get_date_range_display_with_times }}
</td>
{% else %}
<td>
@@ -7,7 +7,7 @@
{% endblocktrans %}</p>
{% endif %}
{% endif %}
<p>{{ plugin.description|safe }}</p>
<p class="plugin-description">{{ plugin.description|safe }}</p>
{% if plugin.restricted and plugin.module not in request.event.settings.allowed_restricted_plugins %}
<p class="text-muted">
<span class="fa fa-info-circle" aria-hidden="true"></span>
@@ -48,19 +48,19 @@
</a>
</td>
</tr>
{% empty %}
{% endfor %}
<tr>
<td colspan="3">
<td colspan="4">
<br>
{% url "control:event.settings.plugins" event=request.event.slug organizer=request.organizer.slug as plugin_settings_url %}
{% blocktrans trimmed with plugin_settings_href='href="'|add:plugin_settings_url|add:'"'|safe %}
There are no payment providers available. Please go to the
<a {{ plugin_settings_href }}>plugin settings</a> and activate one or more payment plugins.
{% endblocktrans %}
<a href="{{ plugin_settings_url }}#tab-0-1-open" class="btn btn-default">
<i class="fa fa-plus"></i> {% trans "Enable additional payment plugins" %}
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</fieldset>
<fieldset>
<legend>{% trans "Deadlines" %}</legend>
@@ -10,20 +10,40 @@
software functionality, connect your event to third-party services, or apply other forms of customizations.
{% endblocktrans %}
</p>
{% if "success" in request.GET %}
<div class="alert alert-success">
{% trans "Your changes have been saved." %}
</div>
{% endif %}
<div class="row">
<div class="col-lg-10">
<p><input type="search" id="plugin_search_input" class="form-control" placeholder="{% trans "Search" %}"></p>
</div>
<div class="col-lg-2 text-right">
<p class="btn-group btn-group-flex" data-toggle="buttons">
<label class="btn btn-primary-if-active active"><input type="radio" name="plugin_state_filter" value="all" checked> {% trans "All" %}</label>
<label class="btn btn-primary-if-active"><input type="radio" name="plugin_state_filter" value="active"> {% trans "Active" %}</label>
</p>
</div>
</div>
<form action="" method="post" class="form-horizontal form-plugins">
{% csrf_token %}
{% if "success" in request.GET %}
<div class="alert alert-success">
{% trans "Your changes have been saved." %}
<div id="plugin_search_results" class="panel panel-default collapse">
<div class="panel-heading">
<button type="button" class="close" aria-label="Close"><span aria-hidden="true">×</span></button>
{% trans "Search results" %}
</div>
{% endif %}
<div class="tabbed-form">
<div class="panel-body">
<div class="plugin-list"></div>
</div>
</div>
<div id="plugin_tabs"><div class="tabbed-form">
{% for cat, catlabel, plist, has_pictures in plugins %}
<fieldset>
<fieldset data-plugin-category="{{ cat }}" data-plugin-category-label="{{ catlabel }}">
<legend>{{ catlabel }}</legend>
<div class="plugin-list">
{% for plugin in plist %}
<div class="plugin-container {% if plugin.featured %}featured-plugin{% endif %}" id="plugin_{{ plugin.module }}">
{% for plugin, is_active, settings_links, navigation_links in plist %}
<div class="plugin-container {% if plugin.featured %}featured-plugin{% endif %}" id="plugin_{{ plugin.module }}" data-plugin-module="{{ plugin.module }}" data-plugin-name="{{ plugin.name }}">
{% if plugin.featured %}
<div class="panel panel-default">
<div class="panel-body">
@@ -49,8 +69,8 @@
{% if show_meta %}
<span class="text-muted text-sm">{{ plugin.version }}</span>
{% endif %}
{% if plugin.module in plugins_active %}
<span class="label label-success">
{% if is_active %}
<span class="label label-success" data-is-active>
<span class="fa fa-check" aria-hidden="true"></span>
{% trans "Active" %}
</span>
@@ -66,8 +86,32 @@
<div class="plugin-action">
<span class="text-muted">{% trans "Not available" %}</span>
</div>
{% elif plugin.module in plugins_active %}
{% elif is_active %}
<div class="plugin-action flip">
{% if navigation_links %}
<div class="btn-group">
<button type="button" class="btn btn-default dropdown-toggle{% if plugin.featured %} btn-lg{% endif %}" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" title="{% trans "Open plugin settings" %}">
<span class="fa fa-compass"></span> {% trans "Go to" %} <span class="caret"></span>
</button>
<ul class="dropdown-menu">
{% for link in navigation_links %}
<li><a href="{{ link.0 }}">{{ link.1 }}</a></li>
{% endfor %}
</ul>
</div>
{% endif %}
{% if settings_links %}
<div class="btn-group">
<button type="button" class="btn btn-default dropdown-toggle{% if plugin.featured %} btn-lg{% endif %}" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" title="{% trans "Open plugin settings" %}">
<span class="fa fa-cog"></span> {% trans "Settings" %} <span class="caret"></span>
</button>
<ul class="dropdown-menu">
{% for link in settings_links %}
<li><a href="{{ link.0 }}">{{ link.1 }}</a></li>
{% endfor %}
</ul>
</div>
{% endif %}
<button class="btn btn-default{% if plugin.featured %} btn-lg{% endif %}" name="plugin:{{ plugin.module }}"
value="disable">{% trans "Disable" %}</button>
</div>
@@ -86,6 +130,7 @@
</div>
</fieldset>
{% endfor %}
</div>
</div></div>
</form>
<script type="text/javascript" src="{% static "pretixcontrol/js/ui/plugins.js" %}"></script>
{% endblock %}
@@ -110,23 +110,26 @@
{% if not hide_orga %}<td>{{ e.organizer }}</td>{% endif %}
<td class="event-date-col">
{% if e.has_subevents %}
{{ e.min_from|default_if_none:""|date:"SHORT_DATETIME_FORMAT" }}
<span class="fa fa-fw- fa-calendar"></span>
{% trans "Event series" %}
<br>
<span class="text-muted">
{% if e.min_from %}
{{ e.min_from|date:"SHORT_DATETIME_FORMAT" }} <br>
{{ e.max_fromto|default_if_none:e.max_to|default_if_none:e.max_from|date:"SHORT_DATETIME_FORMAT" }}
{% else %}
{% trans "No dates" context "subevent" %}
{% endif %}
</span>
{% else %}
{{ e.get_short_date_from_display }}
{% endif %}
{% if e.has_subevents %}
<span class="label label-default">{% trans "Series" %}</span>
{% endif %}
{% if e.settings.show_date_to and e.date_to %}
<br>
{% if e.has_subevents %}
{{ e.max_fromto|default_if_none:e.max_from|default_if_none:e.max_to|default_if_none:""|date:"SHORT_DATETIME_FORMAT" }}
{% else %}
{% if e.settings.show_date_to and e.date_to %}
<br>
{{ e.get_short_date_to_display }}
{% endif %}
{% endif %}
{% if e.settings.timezone != request.timezone %}
<span class="fa fa-globe text-muted" data-toggle="tooltip" title="{{ e.timezone }}"></span>
<span class="fa fa-globe text-muted" data-toggle="tooltip" title="{{ e.tzname }}"></span>
{% endif %}
</td>
<td>
@@ -40,6 +40,10 @@
<tr data-dnd-id="{{ c.id }}">
<td>
<strong><a href="{% url "control:event.items.categories.edit" organizer=request.event.organizer.slug event=request.event.slug category=c.id %}">{{ c.internal_name|default:c.name }}</a></strong>
<br>
<small class="text-muted">
#{{ c.pk }}
</small>
</td>
<td>
{{ c.get_category_type_display }}
@@ -26,6 +26,8 @@
{% bootstrap_field form.condition_ignore_voucher_discounted layout="control" %}
{% if form.subevent_mode %}
{% bootstrap_field form.subevent_mode layout="control" %}
{% bootstrap_field form.subevent_date_from layout="control" %}
{% bootstrap_field form.subevent_date_until layout="control" %}
{% endif %}
<div class="form-group form-alternatives">
<label class="col-md-3 control-label">
@@ -85,7 +85,7 @@
</td>
{% if request.event.has_subevents %}
<td>
{{ q.subevent.name }} {{ q.subevent.get_date_range_display }} {{ q.subevent.date_from|date:"TIME_FORMAT" }}
{{ q.subevent.name }} {{ q.subevent.get_date_range_display_with_times }}
</td>
{% endif %}
<td>{% if q.size == None %}Unlimited{% else %}{{ q.size }}{% endif %}</td>
@@ -9,6 +9,7 @@
{% load eventsignal %}
{% load l10n %}
{% load phone_format %}
{% load getitem %}
{% block title %}
{% blocktrans trimmed with code=order.code %}
Order details: {{ code }}
@@ -397,7 +398,7 @@
{% elif c.auto_checked_in %}
<span class="fa fa-fw fa-magic text-success" data-toggle="tooltip_html" title="{{ c.list.name|force_escape|force_escape }}<br>{% blocktrans trimmed with date=c.datetime|date:'SHORT_DATETIME_FORMAT' %}Automatically checked in: {{ date }}{% endblocktrans %}{% if c.gate %}<br>{{ c.gate }}{% endif %}"></span>
{% else %}
<span class="fa fa-fw fa-check {% if c.list.consider_tickets_used %}text-success{% else %}text-muted{% endif %}" data-toggle="tooltip_html" title="{{ c.list.name|force_escape|force_escape }}<br>{% blocktrans trimmed with date=c.datetime|date:'SHORT_DATETIME_FORMAT' %}Entry scan: {{ date }}{% endblocktrans %}{% if c.gate %}<br>{{ c.gate }}{% endif %}"></span>
<span class="fa fa-fw {% if c.list.consider_tickets_used %}text-success fa-check{% else %}text-muted fa-check-circle-o{% endif %}" data-toggle="tooltip_html" title="{{ c.list.name|force_escape|force_escape }}<br>{% blocktrans trimmed with date=c.datetime|date:'SHORT_DATETIME_FORMAT' %}Entry scan: {{ date }}{% endblocktrans %}{% if c.gate %}<br>{{ c.gate }}{% endif %}"></span>
{% endif %}
{% endfor %}
{% endif %}
@@ -428,11 +429,7 @@
{% endif %}
{% if line.subevent %}
<br/>
<span class="fa fa-calendar fa-fw"></span> {{ line.subevent.name }} &middot; {{ line.subevent.get_date_range_display }}
{% if event.settings.show_times %}
<span class="fa fa-clock-o"></span>
{{ line.subevent.date_from|date:"TIME_FORMAT" }}
{% endif %}
<span class="fa fa-calendar fa-fw"></span> {{ line.subevent.name }} &middot; {{ line.subevent.get_date_range_display_with_times }}
{% endif %}
{% if line.used_membership %}
<br /><span class="fa fa-id-card fa-fw" aria-hidden="true"></span>
@@ -560,8 +557,8 @@
{% if line.street or line.zipcode or line.city or line.country %}
{{ line.street|default_if_none:""|linebreaksbr }}<br>
{{ line.zipcode|default_if_none:"" }} {{ line.city|default_if_none:"" }}<br>
{% if line.state %}{{ line.state_for_address }}<br>{% endif %}
{{ line.country.name|default_if_none:"" }}
{% if line.state %}<br>{{ line.state }}{% endif %}
{% else %}
<em>{% trans "not answered" %}</em>
{% endif %}
@@ -959,7 +956,7 @@
<dt>{% trans "Country" %}</dt>
<dd>{{ order.invoice_address.country.name|default:order.invoice_address.country_old }}</dd>
{% if order.invoice_address.state %}
<dt>{% trans "State" context "address" %}</dt>
<dt>{% trans "State" context "address" as state_label %}{{ COUNTRY_STATE_LABEL|getitem:order.invoice_address.country.code|default:state_label }}</dt>
<dd>{{ order.invoice_address.state_name }}</dd>
{% endif %}
{% if request.event.settings.invoice_address_vatid %}
@@ -51,6 +51,44 @@
{{ log.parsed_data.subject }}</strong>
</p>
<pre>{{ log.parsed_data.message }}</pre>
<ul class="list-unstyled">
{% comment %}
{# Unfortunately, we do not have reliable info whether tickets were attached. #}
{% if log.parsed_data.attach_tickets %}
<li><span class="fa fa-files-o fa-fw"></span> {% trans "Tickets" %}</li>
{% endif %}
{% endcomment %}
{% if log.parsed_data.attach_ical %}
<li><span class="fa fa-calendar-o fa-fw"></span> {% trans "Calendar invite" %}</li>
{% endif %}
{% if log.parsed_data.invoices %}
{% for i in log.parsed_invoices %}
<li>
<span class="fa fa-file-o fa-fw"></span>
<a href="{% url "control:event.invoice.download" invoice=i.pk event=request.event.slug organizer=request.event.organizer.slug %}" target="_blank">
{% if i.is_cancellation %}{% trans "Cancellation" context "invoice" %}{% else %}{% trans "Invoice" %}{% endif %}
{{ i.number }}
</a>
</li>
{% endfor %}
{% endif %}
{% if log.parsed_data.attach_other_files %}
{% for f in log.parsed_other_files %}
<li>
<span class="fa fa-file-o fa-fw"></span>
{{ f }}
</li>
{% endfor %}
{% endif %}
{% if log.parsed_data.attach_cached_files %}
{% for f in log.parsed_data.attach_cached_files %}
<li>
<span class="fa fa-file-o fa-fw"></span>
{{ f }}
</li>
{% endfor %}
{% endif %}
</ul>
{% endif %}
</li>
{% endfor %}
@@ -19,6 +19,9 @@
{% bootstrap_field form.subject layout='horizontal' %}
{% bootstrap_field form.message layout='horizontal' %}
{% bootstrap_field form.attach_tickets layout='horizontal' %}
{% if form.attach_new_order %}
{% bootstrap_field form.attach_new_order layout='horizontal' %}
{% endif %}
{% if form.attach_invoices %}
{% bootstrap_field form.attach_invoices layout='horizontal' %}
{% endif %}
@@ -44,8 +44,7 @@
<form class="form-inline"
action="{% url "control:event.orders.go" event=request.event.slug organizer=request.event.organizer.slug %}">
<p class="input-group">
<input type="text" name="code" class="form-control" placeholder="{% trans "Order code" %}"
autofocus>
<input type="text" name="code" class="form-control" placeholder="{% trans "Order code" %}">
<span class="input-group-btn">
<button class="btn btn-primary" type="submit">{% trans "Go!" %}</button>
</span>
@@ -7,7 +7,8 @@
{% block title %}{% trans "Order search" %}{% endblock %}
{% block content %}
<h1>{% trans "Order search" %}</h1>
<form class="form-horizontal" action="{% url "control:event.orders" event=request.event.slug organizer=request.event.organizer.slug %}" method="get">
<form class="form-horizontal" method="post">
{% csrf_token %}
{% for f in forms %}
{% bootstrap_form_errors f layout='control' %}
{% for field in f %}
@@ -86,23 +86,26 @@
</td>
<td>
{% if e.has_subevents %}
{{ e.min_from|default_if_none:""|date:"SHORT_DATETIME_FORMAT" }}
<span class="fa fa-fw- fa-calendar"></span>
{% trans "Event series" %}
<br>
<span class="text-muted">
{% if e.min_from %}
{{ e.min_from|date:"SHORT_DATETIME_FORMAT" }} <br>
{{ e.max_fromto|default_if_none:e.max_to|default_if_none:e.max_from|date:"SHORT_DATETIME_FORMAT" }}
{% else %}
{% trans "No dates" context "subevent" %}
{% endif %}
</span>
{% else %}
{{ e.get_short_date_from_display }}
{% endif %}
{% if e.has_subevents %}
<span class="label label-default">{% trans "Series" %}</span>
{% endif %}
{% if e.settings.show_date_to and e.date_to %}
<br>
{% if e.has_subevents %}
{{ e.max_fromto|default_if_none:e.max_from|default_if_none:e.max_to|default_if_none:""|date:"SHORT_DATETIME_FORMAT" }}
{% else %}
{% if e.settings.show_date_to and e.date_to %}
<br>
{{ e.get_short_date_to_display }}
{% endif %}
{% endif %}
{% if e.settings.timezone != request.timezone %}
<span class="fa fa-globe text-muted" data-toggle="tooltip" title="{{ e.timezone }}"></span>
<span class="fa fa-globe text-muted" data-toggle="tooltip" title="{{ e.tzname }}"></span>
{% endif %}
</td>
<td>
@@ -182,8 +182,54 @@
</div>
</div>
{% endif %}
<div class="row control-group pdf-info">
<div class="col-sm-12">
<label for="pdf-info-locale">{% trans "Preferred language" %}</label><br>
<select class="form-control" id="pdf-info-locale">
<option value="">{% trans "Order locale" %}</option>
{% for l in locales %}
<option value="{{ l.0 }}">{{ l.1 }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="row control-group pdf-info">
<hr/>
<div class="col-sm-12">
<label>{% trans "Upload PDF as background" %}</label>
<p class="text-muted">
{% blocktrans trimmed %}
You can upload a PDF to use as a custom background.
The paper size will match the PDF.
{% endblocktrans %}
</p>
<p>
<span class="btn btn-default fileinput-button background-button btn-block">
<i class="fa fa-upload"></i>
<span>{% trans "Upload PDF as background" %}</span>
<input id="fileupload" type="file" name="background" accept="application/pdf">
</span>
</p>
<p class="text-center">
<a class="btn btn-link background-download-button" href="{{ pdf }}" target="_blank">
<i class="fa fa-download"></i>
<span class="small">{% trans "Download current background" %}</span>
</a>
</p>
</div>
</div>
<div class="row control-group pdf-info">
<div class="col-sm-12">
<label>{% trans "Or choose custom paper size" %}</label>
<p class="text-muted">
{% blocktrans trimmed %}
To manually change the paper size, you need to create a new, empty background.
{% endblocktrans %}
</p>
</div>
</div>
<div class="row control-group pdf-info">
<div class="col-sm-6">
<label for="pdf-info-width">{% trans "Width (mm)" %}</label><br>
<input type="number" id="pdf-info-width" class="input-block-level form-control">
@@ -195,45 +241,12 @@
</div>
<div class="row control-group pdf-info">
<div class="col-sm-12">
<label>{% trans "Background PDF" %}</label><br>
<p>
<button class="btn btn-default background-button" id="pdf-empty">
<button class="btn btn-default background-button btn-block" id="pdf-empty">
<i class="fa fa-file-o"></i>
{% trans "Create empty background" %}
</button>
</p>
<span class="btn btn-default fileinput-button background-button">
<i class="fa fa-upload"></i>
<span>{% trans "Upload custom background" %}</span>
<input id="fileupload" type="file" name="background" accept="application/pdf">
</span>
</div>
<div class="col-sm-12 help-inline">
<p>
{% blocktrans trimmed %}
After you changed the page size, you need to create a new empty background. If you
want to use a custom background, it already needs to have the correct size.
{% endblocktrans %}
</p>
</div>
<div class="col-sm-12">
<p>
<a class="btn btn-default background-download-button" href="{{ pdf }}" target="_blank">
<i class="fa fa-download"></i>
<span>{% trans "Download current background" %}</span>
</a>
</p>
</div>
</div>
<div class="row control-group pdf-info">
<hr/>
<div class="col-sm-12">
<label for="pdf-info-locale">{% trans "Preferred language" %}</label><br>
<select class="form-control" id="pdf-info-locale">
<option value="">{% trans "Order locale" %}</option>
{% for l in locales %}
<option value="{{ l.0 }}">{{ l.1 }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="row control-group poweredby">
@@ -15,7 +15,7 @@
<form class="form-inline"
action="{% url "control:event.vouchers.go" event=request.event.slug organizer=request.event.organizer.slug %}">
<p class="input-group">
<input type="text" name="code" class="form-control" placeholder="{% trans "Voucher code" %}" autofocus>
<input type="text" name="code" class="form-control" placeholder="{% trans "Voucher code" %}">
<span class="input-group-btn">
<button class="btn btn-primary" type="submit">{% trans "Go!" %}</button>
</span>
@@ -188,10 +188,7 @@
</td>
{% if request.event.has_subevents %}
<td>
{{ v.subevent.name }} {{ v.subevent.get_date_range_display }}
{% if request.event.settings.show_times %}
{{ v.subevent.date_from|date:"TIME_FORMAT" }}
{% endif %}
{{ v.subevent.name }} {{ v.subevent.get_date_range_display_with_times }}
</td>
{% endif %}
<td class="text-right flip">
+55 -12
View File
@@ -34,6 +34,7 @@
# License for the specific language governing permissions and limitations under the License.
import json
import logging
import operator
import re
from collections import OrderedDict
@@ -62,8 +63,9 @@ from django.http import (
from django.shortcuts import get_object_or_404, redirect
from django.urls import reverse
from django.utils.functional import cached_property
from django.utils.html import conditional_escape
from django.utils.html import conditional_escape, format_html
from django.utils.http import url_has_allowed_host_and_scheme
from django.utils.safestring import mark_safe
from django.utils.timezone import now
from django.utils.translation import gettext, gettext_lazy as _, gettext_noop
from django.views.generic import FormView, ListView
@@ -109,6 +111,8 @@ from ...helpers.format import (
from ..logdisplay import OVERVIEW_BANLIST
from . import CreateView, PaginationMixin, UpdateView
logger = logging.getLogger(__name__)
class EventSettingsViewMixin:
def get_context_data(self, **kwargs):
@@ -339,12 +343,29 @@ class EventPlugins(EventSettingsViewMixin, EventPermissionRequiredMixin, Templat
def get_object(self, queryset=None) -> Event:
return self.request.event
def get_context_data(self, *args, **kwargs) -> dict:
def available_plugins(self, event):
from pretix.base.plugins import get_all_plugins
return (p for p in get_all_plugins(event) if not p.name.startswith('.')
and getattr(p, 'visible', True))
def prepare_links(self, pluginmeta, key):
links = getattr(pluginmeta, key, [])
try:
return [
(
reverse(urlname, kwargs={"organizer": self.request.organizer.slug, "event": self.request.event.slug, **kwargs}),
" > ".join(map(str, linktext)) if isinstance(linktext, tuple) else linktext,
) for linktext, urlname, kwargs in links
]
except:
logger.exception('Failed to resolve settings links.')
return []
def get_context_data(self, *args, **kwargs) -> dict:
context = super().get_context_data(*args, **kwargs)
plugins = [p for p in get_all_plugins(self.object) if not p.name.startswith('.')
and getattr(p, 'visible', True)]
plugins = list(self.available_plugins(self.object))
order = [
'FEATURE',
'PAYMENT',
@@ -375,12 +396,18 @@ class EventPlugins(EventSettingsViewMixin, EventPermissionRequiredMixin, Templat
)
plugins_grouped = [(c, list(plist)) for c, plist in plugins_grouped]
active_plugins = self.object.get_plugins()
def plugin_details(plugin):
is_active = plugin.module in active_plugins
settings_links = self.prepare_links(plugin, 'settings_links') if is_active else None
navigation_links = self.prepare_links(plugin, 'navigation_links') if is_active else None
return (plugin, is_active, settings_links, navigation_links)
context['plugins'] = sorted([
(c, labels.get(c, c), plist, any(getattr(p, 'picture', None) for p in plist))
(c, labels.get(c, c), map(plugin_details, plist), any(getattr(p, 'picture', None) for p in plist))
for c, plist
in plugins_grouped
], key=lambda c: (order.index(c[0]), c[1]) if c[0] in order else (999, str(c[1])))
context['plugins_active'] = self.object.get_plugins()
context['show_meta'] = settings.PRETIX_PLUGINS_SHOW_META
return context
@@ -390,13 +417,10 @@ class EventPlugins(EventSettingsViewMixin, EventPermissionRequiredMixin, Templat
return self.render_to_response(context)
def post(self, request, *args, **kwargs):
from pretix.base.plugins import get_all_plugins
self.object = self.get_object()
plugins_available = {
p.module: p for p in get_all_plugins(self.object)
if not p.name.startswith('.') and getattr(p, 'visible', True)
p.module: p for p in self.available_plugins(self.object)
}
with transaction.atomic():
@@ -404,19 +428,38 @@ class EventPlugins(EventSettingsViewMixin, EventPermissionRequiredMixin, Templat
if key.startswith("plugin:"):
module = key.split(":")[1]
if value == "enable" and module in plugins_available:
if getattr(plugins_available[module], 'restricted', False):
pluginmeta = plugins_available[module]
if getattr(pluginmeta, 'restricted', False):
if module not in request.event.settings.allowed_restricted_plugins:
continue
self.request.event.log_action('pretix.event.plugins.enabled', user=self.request.user,
data={'plugin': module})
self.object.enable_plugin(module, allow_restricted=request.event.settings.allowed_restricted_plugins)
links = self.prepare_links(pluginmeta, 'settings_links')
if links:
info = [
'<p>',
format_html(_('The plugin {} is now active, you can configure it here:'),
format_html("<strong>{}</strong>", pluginmeta.name)),
'</p><p>',
] + [
format_html('<a href="{}" class="btn btn-default">{}</a> ', url, text)
for url, text in links
] + ['</p>']
else:
info = [
format_html(_('The plugin {} is now active.'),
format_html("<strong>{}</strong>", pluginmeta.name)),
]
messages.success(self.request, mark_safe("".join(info)))
else:
self.request.event.log_action('pretix.event.plugins.disabled', user=self.request.user,
data={'plugin': module})
self.object.disable_plugin(module)
messages.success(self.request, _('The plugin has been disabled.'))
self.object.save()
messages.success(self.request, _('Your changes have been saved.'))
return redirect(self.get_success_url())
def get_success_url(self) -> str:
+2 -2
View File
@@ -81,9 +81,9 @@ class EventList(PaginationMixin, ListView):
max_to=Max('subevents__date_to'),
max_fromto=Greatest(Max('subevents__date_to'), Max('subevents__date_from'))
).annotate(
order_from=Coalesce('min_from', 'date_from'),
order_from=Coalesce('max_from', 'date_from'),
order_to=Coalesce('max_fromto', 'max_to', 'max_from', 'date_to', 'date_from'),
)
).order_by("-order_from")
qs = qs.prefetch_related(
Prefetch('quotas',
+44
View File
@@ -135,6 +135,7 @@ from pretix.control.views import PaginationMixin
from pretix.helpers import OF_SELF
from pretix.helpers.compat import CompatDeleteView
from pretix.helpers.format import SafeFormatter, format_map
from pretix.helpers.hierarkey import clean_filename
from pretix.helpers.safedownload import check_token
from pretix.presale.signals import question_form_fields
@@ -171,6 +172,26 @@ class OrderSearch(OrderSearchMixin, EventPermissionRequiredMixin, TemplateView):
ctx['forms'] = self.get_forms()
return ctx
def post(self, request, *args, **kwargs):
all_valid = True
for f in self.get_forms():
if not f.is_valid():
all_valid = False
if all_valid:
data = request.POST.copy()
data.pop('csrfmiddlewaretoken', None)
return redirect(reverse(
"control:event.orders",
kwargs={
"event": request.event.slug,
"organizer": request.event.organizer.slug,
}
) + '?' + data.urlencode())
else:
messages.error(request, _("We could not process your input. See below for details."))
return self.get(request, *args, **kwargs)
class BaseOrderBulkActionView(OrderSearchMixin, EventPermissionRequiredMixin, AsyncFormView):
template_name = 'pretixcontrol/orders/bulk_action.html'
@@ -2364,6 +2385,9 @@ class OrderSendMail(EventPermissionRequiredMixin, OrderViewMixin, FormView):
self.request.user, auto_email=False,
attach_tickets=form.cleaned_data.get('attach_tickets', False),
invoices=form.cleaned_data.get('attach_invoices', []),
attach_other_files=[a for a in [
self.request.event.settings.get('mail_attachment_new_order', as_type=str, default='')[len('file://'):]
] if a] if form.cleaned_data.get('attach_new_order', False) else [],
)
messages.success(self.request,
_('Your message has been queued and will be sent to {}.'.format(order.email)))
@@ -2432,6 +2456,9 @@ class OrderPositionSendMail(OrderSendMail):
'pretix.event.order.position.email.custom_sent',
self.request.user,
attach_tickets=form.cleaned_data.get('attach_tickets', False),
attach_other_files=[a for a in [
self.request.event.settings.get('mail_attachment_new_order', as_type=str, default='')[len('file://'):]
] if a] if form.cleaned_data.get('attach_new_order', False) else [],
)
messages.success(self.request,
_('Your message has been queued and will be sent to {}.'.format(position.attendee_email)))
@@ -2461,6 +2488,23 @@ class OrderEmailHistory(EventPermissionRequiredMixin, OrderViewMixin, ListView):
)
return qs
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
for l in ctx["logs"]:
invoice_ids = l.parsed_data.get("invoices")
if invoice_ids:
if type(invoice_ids) is int:
invoice_ids = [invoice_ids]
l.parsed_invoices = Invoice.objects.filter(
event=self.request.event,
pk__in=invoice_ids,
)
if l.parsed_data.get("attach_other_files"):
l.parsed_other_files = [
clean_filename(os.path.basename(f)) for f in l.parsed_data["attach_other_files"]
]
return ctx
class AnswerDownload(EventPermissionRequiredMixin, OrderViewMixin, ListView):
permission = 'can_view_orders'
+10 -5
View File
@@ -44,7 +44,9 @@ import dateutil
from django import forms
from django.conf import settings
from django.contrib import messages
from django.core.exceptions import PermissionDenied, ValidationError
from django.core.exceptions import (
BadRequest, PermissionDenied, ValidationError,
)
from django.core.files import File
from django.db import transaction
from django.db.models import (
@@ -204,9 +206,9 @@ class OrganizerDetail(OrganizerDetailViewMixin, OrganizerPermissionRequiredMixin
max_to=Max('subevents__date_to'),
max_fromto=Greatest(Max('subevents__date_to'), Max('subevents__date_from'))
).annotate(
order_from=Coalesce('min_from', 'date_from'),
order_from=Coalesce('max_from', 'date_from'),
order_to=Coalesce('max_fromto', 'max_to', 'max_from', 'date_to', 'date_from'),
)
).order_by("-order_from")
if self.filter_form.is_valid():
qs = self.filter_form.filter_qs(qs)
return qs
@@ -944,13 +946,16 @@ class DeviceQueryMixin:
qs = self.request.organizer.devices.prefetch_related(
'limit_events', 'gate',
).order_by('revoked', '-device_id')
if self.filter_form.is_valid():
qs = self.filter_form.filter_qs(qs)
if 'device' in self.request_data and '__ALL' not in self.request_data:
qs = qs.filter(
id__in=self.request_data.getlist('device')
)
elif self.request.method == 'GET' or '__ALL' in self.request_data:
if self.filter_form.is_valid():
qs = self.filter_form.filter_qs(qs)
else:
raise BadRequest("No devices selected")
return qs
+20 -3
View File
@@ -104,9 +104,26 @@ class BaseEditorView(EventPermissionRequiredMixin, TemplateView):
scheme = PERSON_NAME_SCHEMES[self.request.event.settings.name_scheme]
sample = {k: str(v) for k, v in scheme['sample'].items()}
p = order.positions.create(item=item, attendee_name_parts=sample, price=item.default_price)
order.positions.create(item=item2, attendee_name_parts=sample, price=item.default_price, addon_to=p)
order.positions.create(item=item2, attendee_name_parts=sample, price=item.default_price, addon_to=p)
p = order.positions.create(
item=item,
attendee_name_parts=sample,
company=_("Sample company"),
price=item.default_price
)
order.positions.create(
item=item2,
attendee_name_parts=sample,
company=_("Sample company"),
price=item.default_price,
addon_to=p
)
order.positions.create(
item=item2,
attendee_name_parts=sample,
company=_("Sample company"),
price=item.default_price,
addon_to=p
)
InvoiceAddress.objects.create(order=order, name_parts=sample, company=_("Sample company"))
return p
+8 -17
View File
@@ -37,12 +37,12 @@ from zoneinfo import ZoneInfo
from dateutil.parser import parse
from django.core.exceptions import PermissionDenied
from django.db.models import F, Max, Min, Q
from django.db.models import Count, F, Max, Min, Q
from django.db.models.functions import Coalesce, Greatest
from django.http import JsonResponse
from django.shortcuts import get_object_or_404
from django.urls import reverse
from django.utils.formats import date_format, get_format
from django.utils.formats import date_format
from django.utils.timezone import make_aware
from django.utils.translation import gettext as _, pgettext
@@ -56,7 +56,7 @@ from pretix.control.permissions import (
event_permission_required, organizer_permission_required,
)
from pretix.helpers.daterange import daterange
from pretix.helpers.i18n import i18ncomp
from pretix.helpers.i18n import i18ncomp, parse_date_localized
def serialize_user(u):
@@ -326,6 +326,9 @@ def nav_context_list(request):
qs_orga = Organizer.objects.filter(pk__in=request.user.teams.values_list('organizer', flat=True))
if query:
qs_orga = qs_orga.filter(Q(name__icontains=query) | Q(slug__icontains=query))
qs_orga = qs_orga.annotate(
n_events=Count("events")
).order_by("-n_events")
if query and len(query) >= 3:
qs_orders = Order.objects.filter(
@@ -405,13 +408,7 @@ def subevent_select2(request, **kwargs):
qf = Q(name__icontains=i18ncomp(query)) | Q(location__icontains=query)
tz = request.event.timezone
dt = None
for f in get_format('DATE_INPUT_FORMATS'):
try:
dt = datetime.strptime(query, f)
break
except (ValueError, TypeError):
continue
dt = parse_date_localized(query)
if dt:
dt_start = make_aware(datetime.combine(dt.date(), time(hour=0, minute=0, second=0)), tz)
@@ -455,13 +452,7 @@ def quotas_select2(request, **kwargs):
qf = Q(name__icontains=query) | Q(subevent__name__icontains=i18ncomp(query))
tz = request.event.timezone
dt = None
for f in get_format('DATE_INPUT_FORMATS'):
try:
dt = datetime.strptime(query, f)
break
except (ValueError, TypeError):
continue
dt = parse_date_localized(query)
if dt and request.event.has_subevents:
dt_start = make_aware(datetime.combine(dt.date(), time(hour=0, minute=0, second=0)), tz)
+1 -1
View File
@@ -629,7 +629,7 @@ class VoucherBulkAction(EventPermissionRequiredMixin, View):
log_entries.append(obj.log_action('pretix.voucher.changed', user=self.request.user, data={
'max_usages': min(obj.redeemed, obj.max_usages),
'bulk': True
}), save=False)
}, save=False))
obj.max_usages = min(obj.redeemed, obj.max_usages)
obj.save(update_fields=['max_usages'])
+26 -11
View File
@@ -33,7 +33,10 @@
# License for the specific language governing permissions and limitations under the License.
from django.utils.html import format_html
from django.utils.translation import get_language, gettext_lazy as _
from django.utils.safestring import mark_safe
from django.utils.translation import (
get_language, gettext_lazy as _, pgettext_lazy,
)
from pretix.helpers.templatetags.date_fast import date_fast as _date
@@ -48,23 +51,28 @@ def daterange(df, dt, as_html=False):
else:
if as_html:
base_format = format_html("<time datetime=\"{}\">{{}}</time>{{}}<time datetime=\"{}\">{{}}</time>", _date(df, "Y-m-d"), _date(dt, "Y-m-d"))
until = format_html(
" <span aria-hidden=\"true\"></span><span class=\"sr-only\"> {until} </span> ",
until=pgettext_lazy("timerange", "until")
)
else:
base_format = "{}{}{}"
until = " "
if lng.startswith("de"):
if df.year == dt.year and df.month == dt.month and df.day == dt.day:
return format_html(base_format, _date(df, "D, j. F Y"))
elif df.year == dt.year and df.month == dt.month:
return format_html(base_format, _date(df, "j."), "", _date(dt, "j. F Y"))
return format_html(base_format, _date(df, "j."), mark_safe(until.strip()), _date(dt, "j. F Y"))
elif df.year == dt.year:
return format_html(base_format, _date(df, "j. F"), " ", _date(dt, "j. F Y"))
return format_html(base_format, _date(df, "j. F"), until, _date(dt, "j. F Y"))
elif lng.startswith("en"):
if df.year == dt.year and df.month == dt.month and df.day == dt.day:
return format_html(base_format, _date(df, "D, N jS, Y"))
elif df.year == dt.year and df.month == dt.month:
return format_html(base_format, _date(df, "N jS"), " ", _date(dt, "jS, Y"))
return format_html(base_format, _date(df, "N jS"), until, _date(dt, "jS, Y"))
elif df.year == dt.year:
return format_html(base_format, _date(df, "N jS"), " ", _date(dt, "N jS, Y"))
return format_html(base_format, _date(df, "N jS"), until, _date(dt, "N jS, Y"))
elif lng.startswith("es"):
if df.year == dt.year and df.month == dt.month and df.day == dt.day:
return format_html(base_format, _date(df, "DATE_FORMAT"))
@@ -72,14 +80,14 @@ def daterange(df, dt, as_html=False):
return format_html(
base_format,
_date(df, "j"),
" - ",
until,
"{} de {} de {}".format(_date(dt, "j"), _date(dt, "F"), _date(dt, "Y"))
)
elif df.year == dt.year:
return format_html(
base_format,
"{} de {}".format(_date(df, "j"), _date(df, "F")),
" - ",
until,
"{} de {} de {}".format(_date(dt, "j"), _date(dt, "F"), _date(dt, "Y"))
)
@@ -89,24 +97,31 @@ def daterange(df, dt, as_html=False):
if as_html:
base_format = "<time datetime=\"{}\">{}</time>"
return format_html(
"{date_from} {date_to}",
"{date_from}{until}{date_to}",
date_from=format_html(base_format, _date(df, "Y-m-d"), _date(df, "DATE_FORMAT")),
date_to=format_html(base_format, _date(dt, "Y-m-d"), _date(dt, "DATE_FORMAT")),
until=until,
)
return _("{date_from} {date_to}").format(
return _("{date_from}{until}{date_to}").format(
date_from=_date(df, "DATE_FORMAT"),
date_to=_date(dt, "DATE_FORMAT"),
until=until,
)
def datetimerange(df, dt, as_html=False):
if as_html:
base_format = format_html("<time datetime=\"{}\">{{}}</time>{{}}<time datetime=\"{}\">{{}}</time>", _date(df, "Y-m-d H:i"), _date(dt, "Y-m-d H:i"))
until = format_html(
" <span aria-hidden=\"true\"></span><span class=\"sr-only\"> {until} </span> ",
until=pgettext_lazy("timerange", "until")
)
else:
base_format = "{}{}{}"
until = " "
if df.year == dt.year and df.month == dt.month and df.day == dt.day:
return format_html(base_format, _date(df, "SHORT_DATE_FORMAT") + " " + _date(df, "TIME_FORMAT"), " ", _date(dt, "TIME_FORMAT"))
return format_html(base_format, _date(df, "SHORT_DATE_FORMAT") + " " + _date(df, "TIME_FORMAT"), until, _date(dt, "TIME_FORMAT"))
else:
return format_html(base_format, _date(df, "SHORT_DATETIME_FORMAT"), " ", _date(dt, "SHORT_DATETIME_FORMAT"))
return format_html(base_format, _date(df, "SHORT_DATETIME_FORMAT"), until, _date(dt, "SHORT_DATETIME_FORMAT"))
+14
View File
@@ -23,7 +23,9 @@ import gettext as gettext_module
import json
import os
import re
from datetime import datetime
from functools import lru_cache
from typing import Optional
from django.apps import apps
from django.conf import settings
@@ -222,3 +224,15 @@ def get_language_score(locale):
else:
score = len(list(catalog.items())) or 1
return score
def parse_date_localized(date_str) -> Optional[datetime]:
"""Parses a date according to the localized date input formats. Returns None if invalid."""
dt = None
for f in get_format('DATE_INPUT_FORMATS'):
try:
dt = datetime.strptime(date_str, f)
break
except (ValueError, TypeError):
continue
return dt
+10
View File
@@ -44,3 +44,13 @@ def modelcopy(obj: models.Model, **kwargs):
else:
setattr(n, f.name, copy.deepcopy(val))
return n
# django 5 contains this in django.utils.choices.flatten_choices
def flatten_choices(choices):
"""Flatten choices by removing nested values."""
for value_or_group, label_or_nested in choices or ():
if isinstance(label_or_nested, (list, tuple)):
yield from label_or_nested
else:
yield value_or_group, label_or_nested
File diff suppressed because it is too large Load Diff
+117 -80
View File
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-01-29 13:18+0000\n"
"POT-Creation-Date: 2025-04-28 11:08+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"
@@ -547,52 +547,52 @@ msgstr ""
msgid "Check-in QR"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:543
#: pretix/static/pretixcontrol/js/ui/editor.js:549
msgid "The PDF background file could not be loaded for the following reason:"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:894
#: pretix/static/pretixcontrol/js/ui/editor.js:903
msgid "Group of objects"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:899
#: pretix/static/pretixcontrol/js/ui/editor.js:908
msgid "Text object (deprecated)"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:901
#: pretix/static/pretixcontrol/js/ui/editor.js:910
msgid "Text box"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:903
#: pretix/static/pretixcontrol/js/ui/editor.js:912
msgid "Barcode area"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:905
#: pretix/static/pretixcontrol/js/ui/editor.js:914
msgid "Image area"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:907
#: pretix/static/pretixcontrol/js/ui/editor.js:916
msgid "Powered by pretix"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:909
#: pretix/static/pretixcontrol/js/ui/editor.js:918
msgid "Object"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:913
#: pretix/static/pretixcontrol/js/ui/editor.js:922
msgid "Ticket design"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:1250
#: pretix/static/pretixcontrol/js/ui/editor.js:1258
msgid "Saving failed."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:1319
#: pretix/static/pretixcontrol/js/ui/editor.js:1370
#: pretix/static/pretixcontrol/js/ui/editor.js:1327
#: pretix/static/pretixcontrol/js/ui/editor.js:1378
msgid "Error while uploading your PDF file, please try again."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:1353
#: pretix/static/pretixcontrol/js/ui/editor.js:1361
msgid "Do you really want to leave the editor without saving your changes?"
msgstr ""
@@ -608,54 +608,54 @@ msgstr ""
msgid "Unknown error."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:318
#: pretix/static/pretixcontrol/js/ui/main.js:330
msgid "Your color has great contrast and is very easy to read!"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:322
#: pretix/static/pretixcontrol/js/ui/main.js:334
msgid "Your color has decent contrast and is probably good-enough to read!"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:326
#: pretix/static/pretixcontrol/js/ui/main.js:338
msgid ""
"Your color has bad contrast for text on white background, please choose a "
"darker shade."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:442
#: pretix/static/pretixcontrol/js/ui/main.js:462
#: pretix/static/pretixcontrol/js/ui/main.js:454
#: pretix/static/pretixcontrol/js/ui/main.js:474
msgid "Search query"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:460
#: pretix/static/pretixcontrol/js/ui/main.js:472
msgid "All"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:461
#: pretix/static/pretixcontrol/js/ui/main.js:473
msgid "None"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:465
#: pretix/static/pretixcontrol/js/ui/main.js:477
msgid "Selected only"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:808
#: pretix/static/pretixcontrol/js/ui/main.js:820
msgid "Enter page number between 1 and %(max)s."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:811
#: pretix/static/pretixcontrol/js/ui/main.js:823
msgid "Invalid page number."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:969
#: pretix/static/pretixcontrol/js/ui/main.js:981
msgid "Use a different name internally"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1009
#: pretix/static/pretixcontrol/js/ui/main.js:1021
msgid "Click to close"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1084
#: pretix/static/pretixcontrol/js/ui/main.js:1102
msgid "You have unsaved changes!"
msgstr ""
@@ -663,6 +663,10 @@ msgstr ""
msgid "Calculating default price…"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/plugins.js:69
msgid "No results"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/question.js:42
msgid "Others"
msgstr ""
@@ -693,32 +697,32 @@ msgid_plural "The items in your cart are reserved for you for {num} minutes."
msgstr[0] ""
msgstr[1] ""
#: pretix/static/pretixpresale/js/ui/main.js:203
#: pretix/static/pretixpresale/js/ui/main.js:215
msgid "The organizer keeps %(currency)s %(amount)s"
msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:211
#: pretix/static/pretixpresale/js/ui/main.js:223
msgid "You get %(currency)s %(amount)s back"
msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:227
#: pretix/static/pretixpresale/js/ui/main.js:239
msgid "Please enter the amount the organizer can keep."
msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:446
#: pretix/static/pretixpresale/js/ui/main.js:458
msgid "Please enter a quantity for one of the ticket types."
msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:498
#: pretix/static/pretixpresale/js/ui/main.js:510
msgid "required"
msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:542
#: pretix/static/pretixpresale/js/ui/main.js:561
#: pretix/static/pretixpresale/js/ui/main.js:554
#: pretix/static/pretixpresale/js/ui/main.js:574
msgid "Time zone:"
msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:552
#: pretix/static/pretixpresale/js/ui/main.js:565
msgid "Your local time:"
msgstr ""
@@ -888,109 +892,114 @@ msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:48
msgctxt "widget"
msgid "The cart could not be created. Please try again later"
msgid "Checkout"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:49
msgctxt "widget"
msgid "The cart could not be created. Please try again later"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:50
msgctxt "widget"
msgid ""
"We could not create your cart, since there are currently too many users in "
"this ticket shop. Please click \"Continue\" to retry in a new tab."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:51
#: pretix/static/pretixpresale/js/widget/widget.js:52
msgctxt "widget"
msgid "Waiting list"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:52
#: pretix/static/pretixpresale/js/widget/widget.js:53
msgctxt "widget"
msgid ""
"You currently have an active cart for this event. If you select more "
"products, they will be added to your existing cart."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:54
#: pretix/static/pretixpresale/js/widget/widget.js:55
msgctxt "widget"
msgid "Resume checkout"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:55
#: pretix/static/pretixpresale/js/widget/widget.js:56
msgctxt "widget"
msgid "Redeem a voucher"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:56
#: pretix/static/pretixpresale/js/widget/widget.js:57
msgctxt "widget"
msgid "Redeem"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:57
#: pretix/static/pretixpresale/js/widget/widget.js:58
msgctxt "widget"
msgid "Voucher code"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:58
#: pretix/static/pretixpresale/js/widget/widget.js:59
msgctxt "widget"
msgid "Close"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:59
#: pretix/static/pretixpresale/js/widget/widget.js:60
msgctxt "widget"
msgid "Continue"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:60
#: pretix/static/pretixpresale/js/widget/widget.js:61
msgctxt "widget"
msgid "Show variants"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:61
#: pretix/static/pretixpresale/js/widget/widget.js:62
msgctxt "widget"
msgid "Hide variants"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:62
#: pretix/static/pretixpresale/js/widget/widget.js:63
msgctxt "widget"
msgid "Choose a different event"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:63
#: pretix/static/pretixpresale/js/widget/widget.js:64
msgctxt "widget"
msgid "Choose a different date"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:64
#: pretix/static/pretixpresale/js/widget/widget.js:65
msgctxt "widget"
msgid "Back"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:65
#: pretix/static/pretixpresale/js/widget/widget.js:66
msgctxt "widget"
msgid "Next month"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:66
#: pretix/static/pretixpresale/js/widget/widget.js:67
msgctxt "widget"
msgid "Previous month"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:67
#: pretix/static/pretixpresale/js/widget/widget.js:68
msgctxt "widget"
msgid "Next week"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:68
#: pretix/static/pretixpresale/js/widget/widget.js:69
msgctxt "widget"
msgid "Previous week"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:69
#: pretix/static/pretixpresale/js/widget/widget.js:70
msgctxt "widget"
msgid "Open seat selection"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:70
#: pretix/static/pretixpresale/js/widget/widget.js:71
msgctxt "widget"
msgid ""
"Some or all ticket categories are currently sold out. If you want, you can "
@@ -998,83 +1007,111 @@ msgid ""
"again."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:71
#: pretix/static/pretixpresale/js/widget/widget.js:72
msgctxt "widget"
msgid "Load more"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:73
#: pretix/static/pretixpresale/js/widget/widget.js:74
msgid "Mo"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:74
#: pretix/static/pretixpresale/js/widget/widget.js:75
msgid "Tu"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:75
#: pretix/static/pretixpresale/js/widget/widget.js:76
msgid "We"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:76
#: pretix/static/pretixpresale/js/widget/widget.js:77
msgid "Th"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:77
#: pretix/static/pretixpresale/js/widget/widget.js:78
msgid "Fr"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:78
#: pretix/static/pretixpresale/js/widget/widget.js:79
msgid "Sa"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:79
#: pretix/static/pretixpresale/js/widget/widget.js:80
msgid "Su"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:81
msgid "Monday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:82
msgid "January"
msgid "Tuesday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:83
msgid "February"
msgid "Wednesday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:84
msgid "March"
msgid "Thursday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:85
msgid "April"
msgid "Friday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:86
msgid "May"
msgid "Saturday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:87
msgid "June"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:88
msgid "July"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:89
msgid "August"
msgid "Sunday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:90
msgid "September"
msgid "January"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:91
msgid "October"
msgid "February"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:92
msgid "November"
msgid "March"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:93
msgid "April"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:94
msgid "May"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:95
msgid "June"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:96
msgid "July"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:97
msgid "August"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:98
msgid "September"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:99
msgid "October"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:100
msgid "November"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:101
msgid "December"
msgstr ""
File diff suppressed because it is too large Load Diff
+116 -74
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-01-29 13:18+0000\n"
"POT-Creation-Date: 2025-04-28 11:08+0000\n"
"PO-Revision-Date: 2021-09-15 11:22+0000\n"
"Last-Translator: Mohamed Tawfiq <mtawfiq@wafyapp.com>\n"
"Language-Team: Arabic <https://translate.pretix.eu/projects/pretix/pretix-js/"
@@ -577,56 +577,56 @@ msgstr ""
msgid "Check-in QR"
msgstr "QR الدخول"
#: pretix/static/pretixcontrol/js/ui/editor.js:543
#: pretix/static/pretixcontrol/js/ui/editor.js:549
msgid "The PDF background file could not be loaded for the following reason:"
msgstr "لا يمكن تحميل ملف PDF الخلفية للأسباب التالية:"
#: pretix/static/pretixcontrol/js/ui/editor.js:894
#: pretix/static/pretixcontrol/js/ui/editor.js:903
msgid "Group of objects"
msgstr "مجموعة من العناصر"
#: pretix/static/pretixcontrol/js/ui/editor.js:899
#: pretix/static/pretixcontrol/js/ui/editor.js:908
#, fuzzy
#| msgid "Text object"
msgid "Text object (deprecated)"
msgstr "عنصر نص"
#: pretix/static/pretixcontrol/js/ui/editor.js:901
#: pretix/static/pretixcontrol/js/ui/editor.js:910
#, fuzzy
#| msgid "Text object"
msgid "Text box"
msgstr "عنصر نص"
#: pretix/static/pretixcontrol/js/ui/editor.js:903
#: pretix/static/pretixcontrol/js/ui/editor.js:912
msgid "Barcode area"
msgstr "منطقة باركود"
#: pretix/static/pretixcontrol/js/ui/editor.js:905
#: pretix/static/pretixcontrol/js/ui/editor.js:914
msgid "Image area"
msgstr "منطقة صورة"
#: pretix/static/pretixcontrol/js/ui/editor.js:907
#: pretix/static/pretixcontrol/js/ui/editor.js:916
msgid "Powered by pretix"
msgstr "مدعوم من pretix"
#: pretix/static/pretixcontrol/js/ui/editor.js:909
#: pretix/static/pretixcontrol/js/ui/editor.js:918
msgid "Object"
msgstr "عنصر"
#: pretix/static/pretixcontrol/js/ui/editor.js:913
#: pretix/static/pretixcontrol/js/ui/editor.js:922
msgid "Ticket design"
msgstr "تصميم التذكرة"
#: pretix/static/pretixcontrol/js/ui/editor.js:1250
#: pretix/static/pretixcontrol/js/ui/editor.js:1258
msgid "Saving failed."
msgstr "فشلت عملية الحفظ."
#: pretix/static/pretixcontrol/js/ui/editor.js:1319
#: pretix/static/pretixcontrol/js/ui/editor.js:1370
#: pretix/static/pretixcontrol/js/ui/editor.js:1327
#: pretix/static/pretixcontrol/js/ui/editor.js:1378
msgid "Error while uploading your PDF file, please try again."
msgstr "حصل خطأ أثناء رفع ملف PDF الخاص بك، يرجى المحاولة مرة أخرى."
#: pretix/static/pretixcontrol/js/ui/editor.js:1353
#: pretix/static/pretixcontrol/js/ui/editor.js:1361
msgid "Do you really want to leave the editor without saving your changes?"
msgstr "هل تريد أن تغادر المحرر دون حفظ التعديلات؟"
@@ -642,54 +642,54 @@ msgstr "توليد الرسائل …"
msgid "Unknown error."
msgstr "خطأ غير معروف."
#: pretix/static/pretixcontrol/js/ui/main.js:318
#: pretix/static/pretixcontrol/js/ui/main.js:330
msgid "Your color has great contrast and is very easy to read!"
msgstr "اللون يتمتع بتباين كبير وتسهل قراءته!"
#: pretix/static/pretixcontrol/js/ui/main.js:322
#: pretix/static/pretixcontrol/js/ui/main.js:334
msgid "Your color has decent contrast and is probably good-enough to read!"
msgstr "اللون يحظى بتباين معقول ويمكن أن يكون مناسب للقراءة!"
#: pretix/static/pretixcontrol/js/ui/main.js:326
#: pretix/static/pretixcontrol/js/ui/main.js:338
msgid ""
"Your color has bad contrast for text on white background, please choose a "
"darker shade."
msgstr "تباين اللون سيئ للخلفية البيضاء، الرجاء اختيار لون غامق."
#: pretix/static/pretixcontrol/js/ui/main.js:442
#: pretix/static/pretixcontrol/js/ui/main.js:462
#: pretix/static/pretixcontrol/js/ui/main.js:454
#: pretix/static/pretixcontrol/js/ui/main.js:474
msgid "Search query"
msgstr "البحث في الاستفسارات"
#: pretix/static/pretixcontrol/js/ui/main.js:460
#: pretix/static/pretixcontrol/js/ui/main.js:472
msgid "All"
msgstr "الكل"
#: pretix/static/pretixcontrol/js/ui/main.js:461
#: pretix/static/pretixcontrol/js/ui/main.js:473
msgid "None"
msgstr "لا شيء"
#: pretix/static/pretixcontrol/js/ui/main.js:465
#: pretix/static/pretixcontrol/js/ui/main.js:477
msgid "Selected only"
msgstr "المختارة فقط"
#: pretix/static/pretixcontrol/js/ui/main.js:808
#: pretix/static/pretixcontrol/js/ui/main.js:820
msgid "Enter page number between 1 and %(max)s."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:811
#: pretix/static/pretixcontrol/js/ui/main.js:823
msgid "Invalid page number."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:969
#: pretix/static/pretixcontrol/js/ui/main.js:981
msgid "Use a different name internally"
msgstr "قم باستخدم اسم مختلف داخليا"
#: pretix/static/pretixcontrol/js/ui/main.js:1009
#: pretix/static/pretixcontrol/js/ui/main.js:1021
msgid "Click to close"
msgstr "اضغط لاغلاق الصفحة"
#: pretix/static/pretixcontrol/js/ui/main.js:1084
#: pretix/static/pretixcontrol/js/ui/main.js:1102
msgid "You have unsaved changes!"
msgstr "لم تقم بحفظ التعديلات!"
@@ -697,6 +697,12 @@ msgstr "لم تقم بحفظ التعديلات!"
msgid "Calculating default price…"
msgstr "حساب السعر الافتراضي…"
#: pretix/static/pretixcontrol/js/ui/plugins.js:69
#, fuzzy
#| msgid "Search results"
msgid "No results"
msgstr "البحث في النتائج"
#: pretix/static/pretixcontrol/js/ui/question.js:42
msgid "Others"
msgstr "غير ذلك"
@@ -741,32 +747,32 @@ msgstr[3] "سيتم حجز العناصر لك في سلة التسوق لعدة
msgstr[4] "سيتم حجز العناصر لك في سلة التسوق لدقائق {num}."
msgstr[5] "سيتم حجز العناصر لك في سلة التسوق لمدة {num}."
#: pretix/static/pretixpresale/js/ui/main.js:203
#: pretix/static/pretixpresale/js/ui/main.js:215
msgid "The organizer keeps %(currency)s %(amount)s"
msgstr "يحصل المنظم على %(currency) %(amount)"
#: pretix/static/pretixpresale/js/ui/main.js:211
#: pretix/static/pretixpresale/js/ui/main.js:223
msgid "You get %(currency)s %(amount)s back"
msgstr "ستسترد %(currency)%(amount)"
#: pretix/static/pretixpresale/js/ui/main.js:227
#: pretix/static/pretixpresale/js/ui/main.js:239
msgid "Please enter the amount the organizer can keep."
msgstr "الرجاء إدخال المبلغ الذي يمكن للمنظم الاحتفاظ به."
#: pretix/static/pretixpresale/js/ui/main.js:446
#: pretix/static/pretixpresale/js/ui/main.js:458
msgid "Please enter a quantity for one of the ticket types."
msgstr "الرجاء إدخال عدد لأحد أنواع التذاكر."
#: pretix/static/pretixpresale/js/ui/main.js:498
#: pretix/static/pretixpresale/js/ui/main.js:510
msgid "required"
msgstr "مطلوب"
#: pretix/static/pretixpresale/js/ui/main.js:542
#: pretix/static/pretixpresale/js/ui/main.js:561
#: pretix/static/pretixpresale/js/ui/main.js:554
#: pretix/static/pretixpresale/js/ui/main.js:574
msgid "Time zone:"
msgstr "المنطقة الزمنية:"
#: pretix/static/pretixpresale/js/ui/main.js:552
#: pretix/static/pretixpresale/js/ui/main.js:565
msgid "Your local time:"
msgstr "التوقيت المحلي:"
@@ -949,23 +955,31 @@ msgid "Open ticket shop"
msgstr "إغلاق متجر التذاكر"
#: pretix/static/pretixpresale/js/widget/widget.js:48
#, fuzzy
#| msgctxt "widget"
#| msgid "Resume checkout"
msgctxt "widget"
msgid "Checkout"
msgstr "استئناف الدفع"
#: pretix/static/pretixpresale/js/widget/widget.js:49
msgctxt "widget"
msgid "The cart could not be created. Please try again later"
msgstr "لا يمكن إنشاء سلة التسوق. الرجاء المحاولة مرة أخرى في وقت لاحق"
#: pretix/static/pretixpresale/js/widget/widget.js:49
#: pretix/static/pretixpresale/js/widget/widget.js:50
msgctxt "widget"
msgid ""
"We could not create your cart, since there are currently too many users in "
"this ticket shop. Please click \"Continue\" to retry in a new tab."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:51
#: pretix/static/pretixpresale/js/widget/widget.js:52
msgctxt "widget"
msgid "Waiting list"
msgstr "قائمة الإنتظار"
#: pretix/static/pretixpresale/js/widget/widget.js:52
#: pretix/static/pretixpresale/js/widget/widget.js:53
msgctxt "widget"
msgid ""
"You currently have an active cart for this event. If you select more "
@@ -974,37 +988,37 @@ msgstr ""
"لديك الآن سلة تسوق مفعلة لهذا الحدث. إذا قمت باختيار منتجات أخرى سيتم "
"إضافتها إلى سلة التسوق الموجودة حالياً."
#: pretix/static/pretixpresale/js/widget/widget.js:54
#: pretix/static/pretixpresale/js/widget/widget.js:55
msgctxt "widget"
msgid "Resume checkout"
msgstr "استئناف الدفع"
#: pretix/static/pretixpresale/js/widget/widget.js:55
#: pretix/static/pretixpresale/js/widget/widget.js:56
msgctxt "widget"
msgid "Redeem a voucher"
msgstr "استبدال قسيمة"
#: pretix/static/pretixpresale/js/widget/widget.js:56
#: pretix/static/pretixpresale/js/widget/widget.js:57
msgctxt "widget"
msgid "Redeem"
msgstr "استبدال"
#: pretix/static/pretixpresale/js/widget/widget.js:57
#: pretix/static/pretixpresale/js/widget/widget.js:58
msgctxt "widget"
msgid "Voucher code"
msgstr "رمز القسيمة"
#: pretix/static/pretixpresale/js/widget/widget.js:58
#: pretix/static/pretixpresale/js/widget/widget.js:59
msgctxt "widget"
msgid "Close"
msgstr "إغلاق"
#: pretix/static/pretixpresale/js/widget/widget.js:59
#: pretix/static/pretixpresale/js/widget/widget.js:60
msgctxt "widget"
msgid "Continue"
msgstr "استمرار"
#: pretix/static/pretixpresale/js/widget/widget.js:60
#: pretix/static/pretixpresale/js/widget/widget.js:61
#, fuzzy
#| msgctxt "widget"
#| msgid "See variations"
@@ -1012,7 +1026,7 @@ msgctxt "widget"
msgid "Show variants"
msgstr "أنظر إلى الاختلافات"
#: pretix/static/pretixpresale/js/widget/widget.js:61
#: pretix/static/pretixpresale/js/widget/widget.js:62
#, fuzzy
#| msgctxt "widget"
#| msgid "See variations"
@@ -1020,47 +1034,47 @@ msgctxt "widget"
msgid "Hide variants"
msgstr "أنظر إلى الاختلافات"
#: pretix/static/pretixpresale/js/widget/widget.js:62
#: pretix/static/pretixpresale/js/widget/widget.js:63
msgctxt "widget"
msgid "Choose a different event"
msgstr "اختر فعالية أخرى"
#: pretix/static/pretixpresale/js/widget/widget.js:63
#: pretix/static/pretixpresale/js/widget/widget.js:64
msgctxt "widget"
msgid "Choose a different date"
msgstr "اختر تاريخا آخر"
#: pretix/static/pretixpresale/js/widget/widget.js:64
#: pretix/static/pretixpresale/js/widget/widget.js:65
msgctxt "widget"
msgid "Back"
msgstr "العودة"
#: pretix/static/pretixpresale/js/widget/widget.js:65
#: pretix/static/pretixpresale/js/widget/widget.js:66
msgctxt "widget"
msgid "Next month"
msgstr "الشهر القادم"
#: pretix/static/pretixpresale/js/widget/widget.js:66
#: pretix/static/pretixpresale/js/widget/widget.js:67
msgctxt "widget"
msgid "Previous month"
msgstr "الشهر السابق"
#: pretix/static/pretixpresale/js/widget/widget.js:67
#: pretix/static/pretixpresale/js/widget/widget.js:68
msgctxt "widget"
msgid "Next week"
msgstr "الأسبوع القادم"
#: pretix/static/pretixpresale/js/widget/widget.js:68
#: pretix/static/pretixpresale/js/widget/widget.js:69
msgctxt "widget"
msgid "Previous week"
msgstr "الأسبوع السابق"
#: pretix/static/pretixpresale/js/widget/widget.js:69
#: pretix/static/pretixpresale/js/widget/widget.js:70
msgctxt "widget"
msgid "Open seat selection"
msgstr "خيارات المقاعد"
#: pretix/static/pretixpresale/js/widget/widget.js:70
#: pretix/static/pretixpresale/js/widget/widget.js:71
msgctxt "widget"
msgid ""
"Some or all ticket categories are currently sold out. If you want, you can "
@@ -1068,86 +1082,114 @@ msgid ""
"again."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:71
#: pretix/static/pretixpresale/js/widget/widget.js:72
#, fuzzy
#| msgid "Load more"
msgctxt "widget"
msgid "Load more"
msgstr "تحميل المزيد"
#: pretix/static/pretixpresale/js/widget/widget.js:73
#: pretix/static/pretixpresale/js/widget/widget.js:74
msgid "Mo"
msgstr "الإثنين"
#: pretix/static/pretixpresale/js/widget/widget.js:74
#: pretix/static/pretixpresale/js/widget/widget.js:75
msgid "Tu"
msgstr "الثلاثاء"
#: pretix/static/pretixpresale/js/widget/widget.js:75
#: pretix/static/pretixpresale/js/widget/widget.js:76
msgid "We"
msgstr "الأربعاء"
#: pretix/static/pretixpresale/js/widget/widget.js:76
#: pretix/static/pretixpresale/js/widget/widget.js:77
msgid "Th"
msgstr "الخميس"
#: pretix/static/pretixpresale/js/widget/widget.js:77
#: pretix/static/pretixpresale/js/widget/widget.js:78
msgid "Fr"
msgstr "الجمعة"
#: pretix/static/pretixpresale/js/widget/widget.js:78
#: pretix/static/pretixpresale/js/widget/widget.js:79
msgid "Sa"
msgstr "السبت"
#: pretix/static/pretixpresale/js/widget/widget.js:79
#: pretix/static/pretixpresale/js/widget/widget.js:80
msgid "Su"
msgstr "الأحد"
#: pretix/static/pretixpresale/js/widget/widget.js:81
msgid "Monday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:82
msgid "Tuesday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:83
msgid "Wednesday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:84
msgid "Thursday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:85
msgid "Friday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:86
msgid "Saturday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:87
msgid "Sunday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:90
msgid "January"
msgstr "يناير"
#: pretix/static/pretixpresale/js/widget/widget.js:83
#: pretix/static/pretixpresale/js/widget/widget.js:91
msgid "February"
msgstr "فبراير"
#: pretix/static/pretixpresale/js/widget/widget.js:84
#: pretix/static/pretixpresale/js/widget/widget.js:92
msgid "March"
msgstr "مارس"
#: pretix/static/pretixpresale/js/widget/widget.js:85
#: pretix/static/pretixpresale/js/widget/widget.js:93
msgid "April"
msgstr "أبريل"
#: pretix/static/pretixpresale/js/widget/widget.js:86
#: pretix/static/pretixpresale/js/widget/widget.js:94
msgid "May"
msgstr "مايو"
#: pretix/static/pretixpresale/js/widget/widget.js:87
#: pretix/static/pretixpresale/js/widget/widget.js:95
msgid "June"
msgstr "يونيو"
#: pretix/static/pretixpresale/js/widget/widget.js:88
#: pretix/static/pretixpresale/js/widget/widget.js:96
msgid "July"
msgstr "يوليو"
#: pretix/static/pretixpresale/js/widget/widget.js:89
#: pretix/static/pretixpresale/js/widget/widget.js:97
msgid "August"
msgstr "أغسطس"
#: pretix/static/pretixpresale/js/widget/widget.js:90
#: pretix/static/pretixpresale/js/widget/widget.js:98
msgid "September"
msgstr "سبتمبر"
#: pretix/static/pretixpresale/js/widget/widget.js:91
#: pretix/static/pretixpresale/js/widget/widget.js:99
msgid "October"
msgstr "أكتوبر"
#: pretix/static/pretixpresale/js/widget/widget.js:92
#: pretix/static/pretixpresale/js/widget/widget.js:100
msgid "November"
msgstr "نوفمبر"
#: pretix/static/pretixpresale/js/widget/widget.js:93
#: pretix/static/pretixpresale/js/widget/widget.js:101
msgid "December"
msgstr "ديسمبر"
File diff suppressed because it is too large Load Diff
+117 -80
View File
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-01-29 13:18+0000\n"
"POT-Creation-Date: 2025-04-28 11:08+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"
@@ -547,52 +547,52 @@ msgstr ""
msgid "Check-in QR"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:543
#: pretix/static/pretixcontrol/js/ui/editor.js:549
msgid "The PDF background file could not be loaded for the following reason:"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:894
#: pretix/static/pretixcontrol/js/ui/editor.js:903
msgid "Group of objects"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:899
#: pretix/static/pretixcontrol/js/ui/editor.js:908
msgid "Text object (deprecated)"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:901
#: pretix/static/pretixcontrol/js/ui/editor.js:910
msgid "Text box"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:903
#: pretix/static/pretixcontrol/js/ui/editor.js:912
msgid "Barcode area"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:905
#: pretix/static/pretixcontrol/js/ui/editor.js:914
msgid "Image area"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:907
#: pretix/static/pretixcontrol/js/ui/editor.js:916
msgid "Powered by pretix"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:909
#: pretix/static/pretixcontrol/js/ui/editor.js:918
msgid "Object"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:913
#: pretix/static/pretixcontrol/js/ui/editor.js:922
msgid "Ticket design"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:1250
#: pretix/static/pretixcontrol/js/ui/editor.js:1258
msgid "Saving failed."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:1319
#: pretix/static/pretixcontrol/js/ui/editor.js:1370
#: pretix/static/pretixcontrol/js/ui/editor.js:1327
#: pretix/static/pretixcontrol/js/ui/editor.js:1378
msgid "Error while uploading your PDF file, please try again."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:1353
#: pretix/static/pretixcontrol/js/ui/editor.js:1361
msgid "Do you really want to leave the editor without saving your changes?"
msgstr ""
@@ -608,54 +608,54 @@ msgstr ""
msgid "Unknown error."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:318
#: pretix/static/pretixcontrol/js/ui/main.js:330
msgid "Your color has great contrast and is very easy to read!"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:322
#: pretix/static/pretixcontrol/js/ui/main.js:334
msgid "Your color has decent contrast and is probably good-enough to read!"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:326
#: pretix/static/pretixcontrol/js/ui/main.js:338
msgid ""
"Your color has bad contrast for text on white background, please choose a "
"darker shade."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:442
#: pretix/static/pretixcontrol/js/ui/main.js:462
#: pretix/static/pretixcontrol/js/ui/main.js:454
#: pretix/static/pretixcontrol/js/ui/main.js:474
msgid "Search query"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:460
#: pretix/static/pretixcontrol/js/ui/main.js:472
msgid "All"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:461
#: pretix/static/pretixcontrol/js/ui/main.js:473
msgid "None"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:465
#: pretix/static/pretixcontrol/js/ui/main.js:477
msgid "Selected only"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:808
#: pretix/static/pretixcontrol/js/ui/main.js:820
msgid "Enter page number between 1 and %(max)s."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:811
#: pretix/static/pretixcontrol/js/ui/main.js:823
msgid "Invalid page number."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:969
#: pretix/static/pretixcontrol/js/ui/main.js:981
msgid "Use a different name internally"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1009
#: pretix/static/pretixcontrol/js/ui/main.js:1021
msgid "Click to close"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1084
#: pretix/static/pretixcontrol/js/ui/main.js:1102
msgid "You have unsaved changes!"
msgstr ""
@@ -663,6 +663,10 @@ msgstr ""
msgid "Calculating default price…"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/plugins.js:69
msgid "No results"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/question.js:42
msgid "Others"
msgstr ""
@@ -693,32 +697,32 @@ msgid_plural "The items in your cart are reserved for you for {num} minutes."
msgstr[0] ""
msgstr[1] ""
#: pretix/static/pretixpresale/js/ui/main.js:203
#: pretix/static/pretixpresale/js/ui/main.js:215
msgid "The organizer keeps %(currency)s %(amount)s"
msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:211
#: pretix/static/pretixpresale/js/ui/main.js:223
msgid "You get %(currency)s %(amount)s back"
msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:227
#: pretix/static/pretixpresale/js/ui/main.js:239
msgid "Please enter the amount the organizer can keep."
msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:446
#: pretix/static/pretixpresale/js/ui/main.js:458
msgid "Please enter a quantity for one of the ticket types."
msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:498
#: pretix/static/pretixpresale/js/ui/main.js:510
msgid "required"
msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:542
#: pretix/static/pretixpresale/js/ui/main.js:561
#: pretix/static/pretixpresale/js/ui/main.js:554
#: pretix/static/pretixpresale/js/ui/main.js:574
msgid "Time zone:"
msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:552
#: pretix/static/pretixpresale/js/ui/main.js:565
msgid "Your local time:"
msgstr ""
@@ -888,109 +892,114 @@ msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:48
msgctxt "widget"
msgid "The cart could not be created. Please try again later"
msgid "Checkout"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:49
msgctxt "widget"
msgid "The cart could not be created. Please try again later"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:50
msgctxt "widget"
msgid ""
"We could not create your cart, since there are currently too many users in "
"this ticket shop. Please click \"Continue\" to retry in a new tab."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:51
#: pretix/static/pretixpresale/js/widget/widget.js:52
msgctxt "widget"
msgid "Waiting list"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:52
#: pretix/static/pretixpresale/js/widget/widget.js:53
msgctxt "widget"
msgid ""
"You currently have an active cart for this event. If you select more "
"products, they will be added to your existing cart."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:54
#: pretix/static/pretixpresale/js/widget/widget.js:55
msgctxt "widget"
msgid "Resume checkout"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:55
#: pretix/static/pretixpresale/js/widget/widget.js:56
msgctxt "widget"
msgid "Redeem a voucher"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:56
#: pretix/static/pretixpresale/js/widget/widget.js:57
msgctxt "widget"
msgid "Redeem"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:57
#: pretix/static/pretixpresale/js/widget/widget.js:58
msgctxt "widget"
msgid "Voucher code"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:58
#: pretix/static/pretixpresale/js/widget/widget.js:59
msgctxt "widget"
msgid "Close"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:59
#: pretix/static/pretixpresale/js/widget/widget.js:60
msgctxt "widget"
msgid "Continue"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:60
#: pretix/static/pretixpresale/js/widget/widget.js:61
msgctxt "widget"
msgid "Show variants"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:61
#: pretix/static/pretixpresale/js/widget/widget.js:62
msgctxt "widget"
msgid "Hide variants"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:62
#: pretix/static/pretixpresale/js/widget/widget.js:63
msgctxt "widget"
msgid "Choose a different event"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:63
#: pretix/static/pretixpresale/js/widget/widget.js:64
msgctxt "widget"
msgid "Choose a different date"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:64
#: pretix/static/pretixpresale/js/widget/widget.js:65
msgctxt "widget"
msgid "Back"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:65
#: pretix/static/pretixpresale/js/widget/widget.js:66
msgctxt "widget"
msgid "Next month"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:66
#: pretix/static/pretixpresale/js/widget/widget.js:67
msgctxt "widget"
msgid "Previous month"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:67
#: pretix/static/pretixpresale/js/widget/widget.js:68
msgctxt "widget"
msgid "Next week"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:68
#: pretix/static/pretixpresale/js/widget/widget.js:69
msgctxt "widget"
msgid "Previous week"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:69
#: pretix/static/pretixpresale/js/widget/widget.js:70
msgctxt "widget"
msgid "Open seat selection"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:70
#: pretix/static/pretixpresale/js/widget/widget.js:71
msgctxt "widget"
msgid ""
"Some or all ticket categories are currently sold out. If you want, you can "
@@ -998,83 +1007,111 @@ msgid ""
"again."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:71
#: pretix/static/pretixpresale/js/widget/widget.js:72
msgctxt "widget"
msgid "Load more"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:73
#: pretix/static/pretixpresale/js/widget/widget.js:74
msgid "Mo"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:74
#: pretix/static/pretixpresale/js/widget/widget.js:75
msgid "Tu"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:75
#: pretix/static/pretixpresale/js/widget/widget.js:76
msgid "We"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:76
#: pretix/static/pretixpresale/js/widget/widget.js:77
msgid "Th"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:77
#: pretix/static/pretixpresale/js/widget/widget.js:78
msgid "Fr"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:78
#: pretix/static/pretixpresale/js/widget/widget.js:79
msgid "Sa"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:79
#: pretix/static/pretixpresale/js/widget/widget.js:80
msgid "Su"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:81
msgid "Monday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:82
msgid "January"
msgid "Tuesday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:83
msgid "February"
msgid "Wednesday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:84
msgid "March"
msgid "Thursday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:85
msgid "April"
msgid "Friday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:86
msgid "May"
msgid "Saturday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:87
msgid "June"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:88
msgid "July"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:89
msgid "August"
msgid "Sunday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:90
msgid "September"
msgid "January"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:91
msgid "October"
msgid "February"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:92
msgid "November"
msgid "March"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:93
msgid "April"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:94
msgid "May"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:95
msgid "June"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:96
msgid "July"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:97
msgid "August"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:98
msgid "September"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:99
msgid "October"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:100
msgid "November"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:101
msgid "December"
msgstr ""
File diff suppressed because it is too large Load Diff
+117 -80
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-01-29 13:18+0000\n"
"POT-Creation-Date: 2025-04-28 11:08+0000\n"
"PO-Revision-Date: 2020-12-19 07:00+0000\n"
"Last-Translator: albert <albert.serra.monner@gmail.com>\n"
"Language-Team: Catalan <https://translate.pretix.eu/projects/pretix/pretix-"
@@ -548,52 +548,52 @@ msgstr ""
msgid "Check-in QR"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:543
#: pretix/static/pretixcontrol/js/ui/editor.js:549
msgid "The PDF background file could not be loaded for the following reason:"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:894
#: pretix/static/pretixcontrol/js/ui/editor.js:903
msgid "Group of objects"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:899
#: pretix/static/pretixcontrol/js/ui/editor.js:908
msgid "Text object (deprecated)"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:901
#: pretix/static/pretixcontrol/js/ui/editor.js:910
msgid "Text box"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:903
#: pretix/static/pretixcontrol/js/ui/editor.js:912
msgid "Barcode area"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:905
#: pretix/static/pretixcontrol/js/ui/editor.js:914
msgid "Image area"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:907
#: pretix/static/pretixcontrol/js/ui/editor.js:916
msgid "Powered by pretix"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:909
#: pretix/static/pretixcontrol/js/ui/editor.js:918
msgid "Object"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:913
#: pretix/static/pretixcontrol/js/ui/editor.js:922
msgid "Ticket design"
msgstr "Disseny del tiquet"
#: pretix/static/pretixcontrol/js/ui/editor.js:1250
#: pretix/static/pretixcontrol/js/ui/editor.js:1258
msgid "Saving failed."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:1319
#: pretix/static/pretixcontrol/js/ui/editor.js:1370
#: pretix/static/pretixcontrol/js/ui/editor.js:1327
#: pretix/static/pretixcontrol/js/ui/editor.js:1378
msgid "Error while uploading your PDF file, please try again."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:1353
#: pretix/static/pretixcontrol/js/ui/editor.js:1361
msgid "Do you really want to leave the editor without saving your changes?"
msgstr ""
@@ -609,54 +609,54 @@ msgstr ""
msgid "Unknown error."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:318
#: pretix/static/pretixcontrol/js/ui/main.js:330
msgid "Your color has great contrast and is very easy to read!"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:322
#: pretix/static/pretixcontrol/js/ui/main.js:334
msgid "Your color has decent contrast and is probably good-enough to read!"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:326
#: pretix/static/pretixcontrol/js/ui/main.js:338
msgid ""
"Your color has bad contrast for text on white background, please choose a "
"darker shade."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:442
#: pretix/static/pretixcontrol/js/ui/main.js:462
#: pretix/static/pretixcontrol/js/ui/main.js:454
#: pretix/static/pretixcontrol/js/ui/main.js:474
msgid "Search query"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:460
#: pretix/static/pretixcontrol/js/ui/main.js:472
msgid "All"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:461
#: pretix/static/pretixcontrol/js/ui/main.js:473
msgid "None"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:465
#: pretix/static/pretixcontrol/js/ui/main.js:477
msgid "Selected only"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:808
#: pretix/static/pretixcontrol/js/ui/main.js:820
msgid "Enter page number between 1 and %(max)s."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:811
#: pretix/static/pretixcontrol/js/ui/main.js:823
msgid "Invalid page number."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:969
#: pretix/static/pretixcontrol/js/ui/main.js:981
msgid "Use a different name internally"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1009
#: pretix/static/pretixcontrol/js/ui/main.js:1021
msgid "Click to close"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1084
#: pretix/static/pretixcontrol/js/ui/main.js:1102
msgid "You have unsaved changes!"
msgstr ""
@@ -664,6 +664,10 @@ msgstr ""
msgid "Calculating default price…"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/plugins.js:69
msgid "No results"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/question.js:42
msgid "Others"
msgstr ""
@@ -698,34 +702,34 @@ msgid_plural "The items in your cart are reserved for you for {num} minutes."
msgstr[0] "El contingut de la cistella ja no el teniu reservat."
msgstr[1] "El contingut de la cistella ja no el teniu reservat."
#: pretix/static/pretixpresale/js/ui/main.js:203
#: pretix/static/pretixpresale/js/ui/main.js:215
msgid "The organizer keeps %(currency)s %(amount)s"
msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:211
#: pretix/static/pretixpresale/js/ui/main.js:223
msgid "You get %(currency)s %(amount)s back"
msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:227
#: pretix/static/pretixpresale/js/ui/main.js:239
msgid "Please enter the amount the organizer can keep."
msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:446
#: pretix/static/pretixpresale/js/ui/main.js:458
msgid "Please enter a quantity for one of the ticket types."
msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:498
#: pretix/static/pretixpresale/js/ui/main.js:510
#, fuzzy
#| msgid "Cart expired"
msgid "required"
msgstr "Cistella expirada"
#: pretix/static/pretixpresale/js/ui/main.js:542
#: pretix/static/pretixpresale/js/ui/main.js:561
#: pretix/static/pretixpresale/js/ui/main.js:554
#: pretix/static/pretixpresale/js/ui/main.js:574
msgid "Time zone:"
msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:552
#: pretix/static/pretixpresale/js/ui/main.js:565
msgid "Your local time:"
msgstr ""
@@ -895,109 +899,114 @@ msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:48
msgctxt "widget"
msgid "The cart could not be created. Please try again later"
msgid "Checkout"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:49
msgctxt "widget"
msgid "The cart could not be created. Please try again later"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:50
msgctxt "widget"
msgid ""
"We could not create your cart, since there are currently too many users in "
"this ticket shop. Please click \"Continue\" to retry in a new tab."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:51
#: pretix/static/pretixpresale/js/widget/widget.js:52
msgctxt "widget"
msgid "Waiting list"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:52
#: pretix/static/pretixpresale/js/widget/widget.js:53
msgctxt "widget"
msgid ""
"You currently have an active cart for this event. If you select more "
"products, they will be added to your existing cart."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:54
#: pretix/static/pretixpresale/js/widget/widget.js:55
msgctxt "widget"
msgid "Resume checkout"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:55
#: pretix/static/pretixpresale/js/widget/widget.js:56
msgctxt "widget"
msgid "Redeem a voucher"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:56
#: pretix/static/pretixpresale/js/widget/widget.js:57
msgctxt "widget"
msgid "Redeem"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:57
#: pretix/static/pretixpresale/js/widget/widget.js:58
msgctxt "widget"
msgid "Voucher code"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:58
#: pretix/static/pretixpresale/js/widget/widget.js:59
msgctxt "widget"
msgid "Close"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:59
#: pretix/static/pretixpresale/js/widget/widget.js:60
msgctxt "widget"
msgid "Continue"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:60
#: pretix/static/pretixpresale/js/widget/widget.js:61
msgctxt "widget"
msgid "Show variants"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:61
#: pretix/static/pretixpresale/js/widget/widget.js:62
msgctxt "widget"
msgid "Hide variants"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:62
#: pretix/static/pretixpresale/js/widget/widget.js:63
msgctxt "widget"
msgid "Choose a different event"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:63
#: pretix/static/pretixpresale/js/widget/widget.js:64
msgctxt "widget"
msgid "Choose a different date"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:64
#: pretix/static/pretixpresale/js/widget/widget.js:65
msgctxt "widget"
msgid "Back"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:65
#: pretix/static/pretixpresale/js/widget/widget.js:66
msgctxt "widget"
msgid "Next month"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:66
#: pretix/static/pretixpresale/js/widget/widget.js:67
msgctxt "widget"
msgid "Previous month"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:67
#: pretix/static/pretixpresale/js/widget/widget.js:68
msgctxt "widget"
msgid "Next week"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:68
#: pretix/static/pretixpresale/js/widget/widget.js:69
msgctxt "widget"
msgid "Previous week"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:69
#: pretix/static/pretixpresale/js/widget/widget.js:70
msgctxt "widget"
msgid "Open seat selection"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:70
#: pretix/static/pretixpresale/js/widget/widget.js:71
msgctxt "widget"
msgid ""
"Some or all ticket categories are currently sold out. If you want, you can "
@@ -1005,83 +1014,111 @@ msgid ""
"again."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:71
#: pretix/static/pretixpresale/js/widget/widget.js:72
msgctxt "widget"
msgid "Load more"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:73
#: pretix/static/pretixpresale/js/widget/widget.js:74
msgid "Mo"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:74
#: pretix/static/pretixpresale/js/widget/widget.js:75
msgid "Tu"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:75
#: pretix/static/pretixpresale/js/widget/widget.js:76
msgid "We"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:76
#: pretix/static/pretixpresale/js/widget/widget.js:77
msgid "Th"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:77
#: pretix/static/pretixpresale/js/widget/widget.js:78
msgid "Fr"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:78
#: pretix/static/pretixpresale/js/widget/widget.js:79
msgid "Sa"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:79
#: pretix/static/pretixpresale/js/widget/widget.js:80
msgid "Su"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:81
msgid "Monday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:82
msgid "January"
msgid "Tuesday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:83
msgid "February"
msgid "Wednesday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:84
msgid "March"
msgid "Thursday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:85
msgid "April"
msgid "Friday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:86
msgid "May"
msgid "Saturday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:87
msgid "June"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:88
msgid "July"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:89
msgid "August"
msgid "Sunday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:90
msgid "September"
msgid "January"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:91
msgid "October"
msgid "February"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:92
msgid "November"
msgid "March"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:93
msgid "April"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:94
msgid "May"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:95
msgid "June"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:96
msgid "July"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:97
msgid "August"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:98
msgid "September"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:99
msgid "October"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:100
msgid "November"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:101
msgid "December"
msgstr ""
File diff suppressed because it is too large Load Diff
+116 -74
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-01-29 13:18+0000\n"
"POT-Creation-Date: 2025-04-28 11:08+0000\n"
"PO-Revision-Date: 2025-02-19 17:00+0000\n"
"Last-Translator: Petr Čermák <pcermak@live.com>\n"
"Language-Team: Czech <https://translate.pretix.eu/projects/pretix/pretix-js/"
@@ -568,56 +568,56 @@ msgstr ""
msgid "Check-in QR"
msgstr "Check-in QR kód"
#: pretix/static/pretixcontrol/js/ui/editor.js:543
#: pretix/static/pretixcontrol/js/ui/editor.js:549
msgid "The PDF background file could not be loaded for the following reason:"
msgstr "Pozadí PDF nemohl být načten:"
#: pretix/static/pretixcontrol/js/ui/editor.js:894
#: pretix/static/pretixcontrol/js/ui/editor.js:903
msgid "Group of objects"
msgstr "Skupina objektů"
#: pretix/static/pretixcontrol/js/ui/editor.js:899
#: pretix/static/pretixcontrol/js/ui/editor.js:908
#, fuzzy
#| msgid "Text object"
msgid "Text object (deprecated)"
msgstr "Textový objekt"
#: pretix/static/pretixcontrol/js/ui/editor.js:901
#: pretix/static/pretixcontrol/js/ui/editor.js:910
#, fuzzy
#| msgid "Text object"
msgid "Text box"
msgstr "Textový objekt"
#: pretix/static/pretixcontrol/js/ui/editor.js:903
#: pretix/static/pretixcontrol/js/ui/editor.js:912
msgid "Barcode area"
msgstr "Oblast s QR kódem"
#: pretix/static/pretixcontrol/js/ui/editor.js:905
#: pretix/static/pretixcontrol/js/ui/editor.js:914
msgid "Image area"
msgstr "Oblast obrazu"
#: pretix/static/pretixcontrol/js/ui/editor.js:907
#: pretix/static/pretixcontrol/js/ui/editor.js:916
msgid "Powered by pretix"
msgstr "Poháněno společností pretix"
#: pretix/static/pretixcontrol/js/ui/editor.js:909
#: pretix/static/pretixcontrol/js/ui/editor.js:918
msgid "Object"
msgstr "Objekt"
#: pretix/static/pretixcontrol/js/ui/editor.js:913
#: pretix/static/pretixcontrol/js/ui/editor.js:922
msgid "Ticket design"
msgstr "Design vstupenky"
#: pretix/static/pretixcontrol/js/ui/editor.js:1250
#: pretix/static/pretixcontrol/js/ui/editor.js:1258
msgid "Saving failed."
msgstr "Uložení se nepodařilo."
#: pretix/static/pretixcontrol/js/ui/editor.js:1319
#: pretix/static/pretixcontrol/js/ui/editor.js:1370
#: pretix/static/pretixcontrol/js/ui/editor.js:1327
#: pretix/static/pretixcontrol/js/ui/editor.js:1378
msgid "Error while uploading your PDF file, please try again."
msgstr "Při nahrávání souboru PDF došlo k problému, zkuste to prosím znovu."
#: pretix/static/pretixcontrol/js/ui/editor.js:1353
#: pretix/static/pretixcontrol/js/ui/editor.js:1361
msgid "Do you really want to leave the editor without saving your changes?"
msgstr "Opravdu chcete opustit editor bez uložení změn?"
@@ -633,16 +633,16 @@ msgstr "Vytváření zpráv…"
msgid "Unknown error."
msgstr "Neznámá chyba."
#: pretix/static/pretixcontrol/js/ui/main.js:318
#: pretix/static/pretixcontrol/js/ui/main.js:330
msgid "Your color has great contrast and is very easy to read!"
msgstr "Tato barva má velmi dobrý kontrast a je velmi dobře čitelná!"
#: pretix/static/pretixcontrol/js/ui/main.js:322
#: pretix/static/pretixcontrol/js/ui/main.js:334
msgid "Your color has decent contrast and is probably good-enough to read!"
msgstr ""
"Tato barva má slušný kontrast a pravděpodobně je dostatečně dobře čitelná!"
#: pretix/static/pretixcontrol/js/ui/main.js:326
#: pretix/static/pretixcontrol/js/ui/main.js:338
msgid ""
"Your color has bad contrast for text on white background, please choose a "
"darker shade."
@@ -650,40 +650,40 @@ msgstr ""
"Tato barva je pro text na bílém pozadí špatně kontrastní, zvolte prosím "
"tmavší odstín."
#: pretix/static/pretixcontrol/js/ui/main.js:442
#: pretix/static/pretixcontrol/js/ui/main.js:462
#: pretix/static/pretixcontrol/js/ui/main.js:454
#: pretix/static/pretixcontrol/js/ui/main.js:474
msgid "Search query"
msgstr "Hledaný výraz"
#: pretix/static/pretixcontrol/js/ui/main.js:460
#: pretix/static/pretixcontrol/js/ui/main.js:472
msgid "All"
msgstr "Všechny"
#: pretix/static/pretixcontrol/js/ui/main.js:461
#: pretix/static/pretixcontrol/js/ui/main.js:473
msgid "None"
msgstr "Žádný"
#: pretix/static/pretixcontrol/js/ui/main.js:465
#: pretix/static/pretixcontrol/js/ui/main.js:477
msgid "Selected only"
msgstr "Pouze vybrané"
#: pretix/static/pretixcontrol/js/ui/main.js:808
#: pretix/static/pretixcontrol/js/ui/main.js:820
msgid "Enter page number between 1 and %(max)s."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:811
#: pretix/static/pretixcontrol/js/ui/main.js:823
msgid "Invalid page number."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:969
#: pretix/static/pretixcontrol/js/ui/main.js:981
msgid "Use a different name internally"
msgstr "Interně používat jiný název"
#: pretix/static/pretixcontrol/js/ui/main.js:1009
#: pretix/static/pretixcontrol/js/ui/main.js:1021
msgid "Click to close"
msgstr "Kliknutím zavřete"
#: pretix/static/pretixcontrol/js/ui/main.js:1084
#: pretix/static/pretixcontrol/js/ui/main.js:1102
msgid "You have unsaved changes!"
msgstr "Máte neuložené změny!"
@@ -691,6 +691,12 @@ msgstr "Máte neuložené změny!"
msgid "Calculating default price…"
msgstr "Výpočet standardní ceny…"
#: pretix/static/pretixcontrol/js/ui/plugins.js:69
#, fuzzy
#| msgid "Search results"
msgid "No results"
msgstr "Vyhledat výsledky"
#: pretix/static/pretixcontrol/js/ui/question.js:42
msgid "Others"
msgstr "Další"
@@ -728,32 +734,32 @@ msgstr[1] ""
msgstr[2] ""
"Produkty v nákupním košíku jsou pro vás rezervovány na dalších {num} minut."
#: pretix/static/pretixpresale/js/ui/main.js:203
#: pretix/static/pretixpresale/js/ui/main.js:215
msgid "The organizer keeps %(currency)s %(amount)s"
msgstr "Organizátor si ponechává %(currency)s %(amount)s"
#: pretix/static/pretixpresale/js/ui/main.js:211
#: pretix/static/pretixpresale/js/ui/main.js:223
msgid "You get %(currency)s %(amount)s back"
msgstr "Dostanete %(currency)s %(amount)s zpět"
#: pretix/static/pretixpresale/js/ui/main.js:227
#: pretix/static/pretixpresale/js/ui/main.js:239
msgid "Please enter the amount the organizer can keep."
msgstr "Zadejte částku, kterou si organizátor může ponechat."
#: pretix/static/pretixpresale/js/ui/main.js:446
#: pretix/static/pretixpresale/js/ui/main.js:458
msgid "Please enter a quantity for one of the ticket types."
msgstr "Zadejte prosím množství pro jeden z typů vstupenek."
#: pretix/static/pretixpresale/js/ui/main.js:498
#: pretix/static/pretixpresale/js/ui/main.js:510
msgid "required"
msgstr "povinný"
#: pretix/static/pretixpresale/js/ui/main.js:542
#: pretix/static/pretixpresale/js/ui/main.js:561
#: pretix/static/pretixpresale/js/ui/main.js:554
#: pretix/static/pretixpresale/js/ui/main.js:574
msgid "Time zone:"
msgstr "Časové pásmo:"
#: pretix/static/pretixpresale/js/ui/main.js:552
#: pretix/static/pretixpresale/js/ui/main.js:565
msgid "Your local time:"
msgstr "Místní čas:"
@@ -936,11 +942,19 @@ msgid "Open ticket shop"
msgstr "Obchod vstupenek otevřit"
#: pretix/static/pretixpresale/js/widget/widget.js:48
#, fuzzy
#| msgctxt "widget"
#| msgid "Resume checkout"
msgctxt "widget"
msgid "Checkout"
msgstr "Obnovit checkout"
#: pretix/static/pretixpresale/js/widget/widget.js:49
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:49
#: pretix/static/pretixpresale/js/widget/widget.js:50
msgctxt "widget"
msgid ""
"We could not create your cart, since there are currently too many users in "
@@ -950,12 +964,12 @@ 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:51
#: pretix/static/pretixpresale/js/widget/widget.js:52
msgctxt "widget"
msgid "Waiting list"
msgstr "Čekací listina"
#: pretix/static/pretixpresale/js/widget/widget.js:52
#: pretix/static/pretixpresale/js/widget/widget.js:53
msgctxt "widget"
msgid ""
"You currently have an active cart for this event. If you select more "
@@ -964,37 +978,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:54
#: pretix/static/pretixpresale/js/widget/widget.js:55
msgctxt "widget"
msgid "Resume checkout"
msgstr "Obnovit checkout"
#: pretix/static/pretixpresale/js/widget/widget.js:55
#: pretix/static/pretixpresale/js/widget/widget.js:56
msgctxt "widget"
msgid "Redeem a voucher"
msgstr "Uplatnit poukázku"
#: pretix/static/pretixpresale/js/widget/widget.js:56
#: pretix/static/pretixpresale/js/widget/widget.js:57
msgctxt "widget"
msgid "Redeem"
msgstr "Uplatnit"
#: pretix/static/pretixpresale/js/widget/widget.js:57
#: pretix/static/pretixpresale/js/widget/widget.js:58
msgctxt "widget"
msgid "Voucher code"
msgstr "Kód poukázky"
#: pretix/static/pretixpresale/js/widget/widget.js:58
#: pretix/static/pretixpresale/js/widget/widget.js:59
msgctxt "widget"
msgid "Close"
msgstr "Zavřít"
#: pretix/static/pretixpresale/js/widget/widget.js:59
#: pretix/static/pretixpresale/js/widget/widget.js:60
msgctxt "widget"
msgid "Continue"
msgstr "Pokračovat"
#: pretix/static/pretixpresale/js/widget/widget.js:60
#: pretix/static/pretixpresale/js/widget/widget.js:61
#, fuzzy
#| msgctxt "widget"
#| msgid "See variations"
@@ -1002,7 +1016,7 @@ msgctxt "widget"
msgid "Show variants"
msgstr "Zobrazit možnosti"
#: pretix/static/pretixpresale/js/widget/widget.js:61
#: pretix/static/pretixpresale/js/widget/widget.js:62
#, fuzzy
#| msgctxt "widget"
#| msgid "See variations"
@@ -1010,47 +1024,47 @@ msgctxt "widget"
msgid "Hide variants"
msgstr "Zobrazit možnosti"
#: pretix/static/pretixpresale/js/widget/widget.js:62
#: pretix/static/pretixpresale/js/widget/widget.js:63
msgctxt "widget"
msgid "Choose a different event"
msgstr "Vybrat jinou událost"
#: pretix/static/pretixpresale/js/widget/widget.js:63
#: pretix/static/pretixpresale/js/widget/widget.js:64
msgctxt "widget"
msgid "Choose a different date"
msgstr "Vybrat jiný datum"
#: pretix/static/pretixpresale/js/widget/widget.js:64
#: pretix/static/pretixpresale/js/widget/widget.js:65
msgctxt "widget"
msgid "Back"
msgstr "Zpět"
#: pretix/static/pretixpresale/js/widget/widget.js:65
#: pretix/static/pretixpresale/js/widget/widget.js:66
msgctxt "widget"
msgid "Next month"
msgstr "Následující měsíc"
#: pretix/static/pretixpresale/js/widget/widget.js:66
#: pretix/static/pretixpresale/js/widget/widget.js:67
msgctxt "widget"
msgid "Previous month"
msgstr "Předchozí měsíc"
#: pretix/static/pretixpresale/js/widget/widget.js:67
#: pretix/static/pretixpresale/js/widget/widget.js:68
msgctxt "widget"
msgid "Next week"
msgstr "Příští týden"
#: pretix/static/pretixpresale/js/widget/widget.js:68
#: pretix/static/pretixpresale/js/widget/widget.js:69
msgctxt "widget"
msgid "Previous week"
msgstr "Předchozí týden"
#: pretix/static/pretixpresale/js/widget/widget.js:69
#: pretix/static/pretixpresale/js/widget/widget.js:70
msgctxt "widget"
msgid "Open seat selection"
msgstr "Otevřete výběr sedadla"
#: pretix/static/pretixpresale/js/widget/widget.js:70
#: pretix/static/pretixpresale/js/widget/widget.js:71
msgctxt "widget"
msgid ""
"Some or all ticket categories are currently sold out. If you want, you can "
@@ -1061,84 +1075,112 @@ 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:71
#: pretix/static/pretixpresale/js/widget/widget.js:72
msgctxt "widget"
msgid "Load more"
msgstr "Načíst více"
#: pretix/static/pretixpresale/js/widget/widget.js:73
#: pretix/static/pretixpresale/js/widget/widget.js:74
msgid "Mo"
msgstr "Po"
#: pretix/static/pretixpresale/js/widget/widget.js:74
#: pretix/static/pretixpresale/js/widget/widget.js:75
msgid "Tu"
msgstr "Út"
#: pretix/static/pretixpresale/js/widget/widget.js:75
#: pretix/static/pretixpresale/js/widget/widget.js:76
msgid "We"
msgstr "St"
#: pretix/static/pretixpresale/js/widget/widget.js:76
#: pretix/static/pretixpresale/js/widget/widget.js:77
msgid "Th"
msgstr "Čt"
#: pretix/static/pretixpresale/js/widget/widget.js:77
#: pretix/static/pretixpresale/js/widget/widget.js:78
msgid "Fr"
msgstr "Pá"
#: pretix/static/pretixpresale/js/widget/widget.js:78
#: pretix/static/pretixpresale/js/widget/widget.js:79
msgid "Sa"
msgstr "So"
#: pretix/static/pretixpresale/js/widget/widget.js:79
#: pretix/static/pretixpresale/js/widget/widget.js:80
msgid "Su"
msgstr "Ne"
#: pretix/static/pretixpresale/js/widget/widget.js:81
msgid "Monday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:82
msgid "Tuesday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:83
msgid "Wednesday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:84
msgid "Thursday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:85
msgid "Friday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:86
msgid "Saturday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:87
msgid "Sunday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:90
msgid "January"
msgstr "Leden"
#: pretix/static/pretixpresale/js/widget/widget.js:83
#: pretix/static/pretixpresale/js/widget/widget.js:91
msgid "February"
msgstr "Únor"
#: pretix/static/pretixpresale/js/widget/widget.js:84
#: pretix/static/pretixpresale/js/widget/widget.js:92
msgid "March"
msgstr "Březen"
#: pretix/static/pretixpresale/js/widget/widget.js:85
#: pretix/static/pretixpresale/js/widget/widget.js:93
msgid "April"
msgstr "Duben"
#: pretix/static/pretixpresale/js/widget/widget.js:86
#: pretix/static/pretixpresale/js/widget/widget.js:94
msgid "May"
msgstr "Květen"
#: pretix/static/pretixpresale/js/widget/widget.js:87
#: pretix/static/pretixpresale/js/widget/widget.js:95
msgid "June"
msgstr "červen"
#: pretix/static/pretixpresale/js/widget/widget.js:88
#: pretix/static/pretixpresale/js/widget/widget.js:96
msgid "July"
msgstr "Červenec"
#: pretix/static/pretixpresale/js/widget/widget.js:89
#: pretix/static/pretixpresale/js/widget/widget.js:97
msgid "August"
msgstr "Srpen"
#: pretix/static/pretixpresale/js/widget/widget.js:90
#: pretix/static/pretixpresale/js/widget/widget.js:98
msgid "September"
msgstr "Září"
#: pretix/static/pretixpresale/js/widget/widget.js:91
#: pretix/static/pretixpresale/js/widget/widget.js:99
msgid "October"
msgstr "Říjen"
#: pretix/static/pretixpresale/js/widget/widget.js:92
#: pretix/static/pretixpresale/js/widget/widget.js:100
msgid "November"
msgstr "Listopad"
#: pretix/static/pretixpresale/js/widget/widget.js:93
#: pretix/static/pretixpresale/js/widget/widget.js:101
msgid "December"
msgstr "Prosinec"
File diff suppressed because it is too large Load Diff
+117 -80
View File
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-01-29 13:18+0000\n"
"POT-Creation-Date: 2025-04-28 11:08+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"
@@ -548,52 +548,52 @@ msgstr ""
msgid "Check-in QR"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:543
#: pretix/static/pretixcontrol/js/ui/editor.js:549
msgid "The PDF background file could not be loaded for the following reason:"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:894
#: pretix/static/pretixcontrol/js/ui/editor.js:903
msgid "Group of objects"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:899
#: pretix/static/pretixcontrol/js/ui/editor.js:908
msgid "Text object (deprecated)"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:901
#: pretix/static/pretixcontrol/js/ui/editor.js:910
msgid "Text box"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:903
#: pretix/static/pretixcontrol/js/ui/editor.js:912
msgid "Barcode area"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:905
#: pretix/static/pretixcontrol/js/ui/editor.js:914
msgid "Image area"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:907
#: pretix/static/pretixcontrol/js/ui/editor.js:916
msgid "Powered by pretix"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:909
#: pretix/static/pretixcontrol/js/ui/editor.js:918
msgid "Object"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:913
#: pretix/static/pretixcontrol/js/ui/editor.js:922
msgid "Ticket design"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:1250
#: pretix/static/pretixcontrol/js/ui/editor.js:1258
msgid "Saving failed."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:1319
#: pretix/static/pretixcontrol/js/ui/editor.js:1370
#: pretix/static/pretixcontrol/js/ui/editor.js:1327
#: pretix/static/pretixcontrol/js/ui/editor.js:1378
msgid "Error while uploading your PDF file, please try again."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:1353
#: pretix/static/pretixcontrol/js/ui/editor.js:1361
msgid "Do you really want to leave the editor without saving your changes?"
msgstr ""
@@ -609,54 +609,54 @@ msgstr ""
msgid "Unknown error."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:318
#: pretix/static/pretixcontrol/js/ui/main.js:330
msgid "Your color has great contrast and is very easy to read!"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:322
#: pretix/static/pretixcontrol/js/ui/main.js:334
msgid "Your color has decent contrast and is probably good-enough to read!"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:326
#: pretix/static/pretixcontrol/js/ui/main.js:338
msgid ""
"Your color has bad contrast for text on white background, please choose a "
"darker shade."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:442
#: pretix/static/pretixcontrol/js/ui/main.js:462
#: pretix/static/pretixcontrol/js/ui/main.js:454
#: pretix/static/pretixcontrol/js/ui/main.js:474
msgid "Search query"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:460
#: pretix/static/pretixcontrol/js/ui/main.js:472
msgid "All"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:461
#: pretix/static/pretixcontrol/js/ui/main.js:473
msgid "None"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:465
#: pretix/static/pretixcontrol/js/ui/main.js:477
msgid "Selected only"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:808
#: pretix/static/pretixcontrol/js/ui/main.js:820
msgid "Enter page number between 1 and %(max)s."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:811
#: pretix/static/pretixcontrol/js/ui/main.js:823
msgid "Invalid page number."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:969
#: pretix/static/pretixcontrol/js/ui/main.js:981
msgid "Use a different name internally"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1009
#: pretix/static/pretixcontrol/js/ui/main.js:1021
msgid "Click to close"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1084
#: pretix/static/pretixcontrol/js/ui/main.js:1102
msgid "You have unsaved changes!"
msgstr ""
@@ -664,6 +664,10 @@ msgstr ""
msgid "Calculating default price…"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/plugins.js:69
msgid "No results"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/question.js:42
msgid "Others"
msgstr ""
@@ -694,32 +698,32 @@ msgid_plural "The items in your cart are reserved for you for {num} minutes."
msgstr[0] ""
msgstr[1] ""
#: pretix/static/pretixpresale/js/ui/main.js:203
#: pretix/static/pretixpresale/js/ui/main.js:215
msgid "The organizer keeps %(currency)s %(amount)s"
msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:211
#: pretix/static/pretixpresale/js/ui/main.js:223
msgid "You get %(currency)s %(amount)s back"
msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:227
#: pretix/static/pretixpresale/js/ui/main.js:239
msgid "Please enter the amount the organizer can keep."
msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:446
#: pretix/static/pretixpresale/js/ui/main.js:458
msgid "Please enter a quantity for one of the ticket types."
msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:498
#: pretix/static/pretixpresale/js/ui/main.js:510
msgid "required"
msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:542
#: pretix/static/pretixpresale/js/ui/main.js:561
#: pretix/static/pretixpresale/js/ui/main.js:554
#: pretix/static/pretixpresale/js/ui/main.js:574
msgid "Time zone:"
msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:552
#: pretix/static/pretixpresale/js/ui/main.js:565
msgid "Your local time:"
msgstr ""
@@ -889,109 +893,114 @@ msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:48
msgctxt "widget"
msgid "The cart could not be created. Please try again later"
msgid "Checkout"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:49
msgctxt "widget"
msgid "The cart could not be created. Please try again later"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:50
msgctxt "widget"
msgid ""
"We could not create your cart, since there are currently too many users in "
"this ticket shop. Please click \"Continue\" to retry in a new tab."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:51
#: pretix/static/pretixpresale/js/widget/widget.js:52
msgctxt "widget"
msgid "Waiting list"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:52
#: pretix/static/pretixpresale/js/widget/widget.js:53
msgctxt "widget"
msgid ""
"You currently have an active cart for this event. If you select more "
"products, they will be added to your existing cart."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:54
#: pretix/static/pretixpresale/js/widget/widget.js:55
msgctxt "widget"
msgid "Resume checkout"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:55
#: pretix/static/pretixpresale/js/widget/widget.js:56
msgctxt "widget"
msgid "Redeem a voucher"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:56
#: pretix/static/pretixpresale/js/widget/widget.js:57
msgctxt "widget"
msgid "Redeem"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:57
#: pretix/static/pretixpresale/js/widget/widget.js:58
msgctxt "widget"
msgid "Voucher code"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:58
#: pretix/static/pretixpresale/js/widget/widget.js:59
msgctxt "widget"
msgid "Close"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:59
#: pretix/static/pretixpresale/js/widget/widget.js:60
msgctxt "widget"
msgid "Continue"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:60
#: pretix/static/pretixpresale/js/widget/widget.js:61
msgctxt "widget"
msgid "Show variants"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:61
#: pretix/static/pretixpresale/js/widget/widget.js:62
msgctxt "widget"
msgid "Hide variants"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:62
#: pretix/static/pretixpresale/js/widget/widget.js:63
msgctxt "widget"
msgid "Choose a different event"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:63
#: pretix/static/pretixpresale/js/widget/widget.js:64
msgctxt "widget"
msgid "Choose a different date"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:64
#: pretix/static/pretixpresale/js/widget/widget.js:65
msgctxt "widget"
msgid "Back"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:65
#: pretix/static/pretixpresale/js/widget/widget.js:66
msgctxt "widget"
msgid "Next month"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:66
#: pretix/static/pretixpresale/js/widget/widget.js:67
msgctxt "widget"
msgid "Previous month"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:67
#: pretix/static/pretixpresale/js/widget/widget.js:68
msgctxt "widget"
msgid "Next week"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:68
#: pretix/static/pretixpresale/js/widget/widget.js:69
msgctxt "widget"
msgid "Previous week"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:69
#: pretix/static/pretixpresale/js/widget/widget.js:70
msgctxt "widget"
msgid "Open seat selection"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:70
#: pretix/static/pretixpresale/js/widget/widget.js:71
msgctxt "widget"
msgid ""
"Some or all ticket categories are currently sold out. If you want, you can "
@@ -999,83 +1008,111 @@ msgid ""
"again."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:71
#: pretix/static/pretixpresale/js/widget/widget.js:72
msgctxt "widget"
msgid "Load more"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:73
#: pretix/static/pretixpresale/js/widget/widget.js:74
msgid "Mo"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:74
#: pretix/static/pretixpresale/js/widget/widget.js:75
msgid "Tu"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:75
#: pretix/static/pretixpresale/js/widget/widget.js:76
msgid "We"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:76
#: pretix/static/pretixpresale/js/widget/widget.js:77
msgid "Th"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:77
#: pretix/static/pretixpresale/js/widget/widget.js:78
msgid "Fr"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:78
#: pretix/static/pretixpresale/js/widget/widget.js:79
msgid "Sa"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:79
#: pretix/static/pretixpresale/js/widget/widget.js:80
msgid "Su"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:81
msgid "Monday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:82
msgid "January"
msgid "Tuesday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:83
msgid "February"
msgid "Wednesday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:84
msgid "March"
msgid "Thursday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:85
msgid "April"
msgid "Friday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:86
msgid "May"
msgid "Saturday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:87
msgid "June"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:88
msgid "July"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:89
msgid "August"
msgid "Sunday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:90
msgid "September"
msgid "January"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:91
msgid "October"
msgid "February"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:92
msgid "November"
msgid "March"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:93
msgid "April"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:94
msgid "May"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:95
msgid "June"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:96
msgid "July"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:97
msgid "August"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:98
msgid "September"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:99
msgid "October"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:100
msgid "November"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:101
msgid "December"
msgstr ""
File diff suppressed because it is too large Load Diff
+116 -74
View File
@@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-01-29 13:18+0000\n"
"POT-Creation-Date: 2025-04-28 11:08+0000\n"
"PO-Revision-Date: 2024-07-10 15:00+0000\n"
"Last-Translator: Nikolai <nikolai@lengefeldt.de>\n"
"Language-Team: Danish <https://translate.pretix.eu/projects/pretix/pretix-js/"
@@ -588,58 +588,58 @@ msgstr ""
msgid "Check-in QR"
msgstr "Check-in QR"
#: pretix/static/pretixcontrol/js/ui/editor.js:543
#: pretix/static/pretixcontrol/js/ui/editor.js:549
msgid "The PDF background file could not be loaded for the following reason:"
msgstr "Baggrunds-pdf'en kunne ikke hentes af følgende grund:"
#: pretix/static/pretixcontrol/js/ui/editor.js:894
#: pretix/static/pretixcontrol/js/ui/editor.js:903
msgid "Group of objects"
msgstr "Gruppe af objekter"
#: pretix/static/pretixcontrol/js/ui/editor.js:899
#: pretix/static/pretixcontrol/js/ui/editor.js:908
#, fuzzy
#| msgid "Text object"
msgid "Text object (deprecated)"
msgstr "Tekstobjekt"
#: pretix/static/pretixcontrol/js/ui/editor.js:901
#: pretix/static/pretixcontrol/js/ui/editor.js:910
#, fuzzy
#| msgid "Text object"
msgid "Text box"
msgstr "Tekstobjekt"
#: pretix/static/pretixcontrol/js/ui/editor.js:903
#: pretix/static/pretixcontrol/js/ui/editor.js:912
msgid "Barcode area"
msgstr "QR-kode-område"
#: pretix/static/pretixcontrol/js/ui/editor.js:905
#: pretix/static/pretixcontrol/js/ui/editor.js:914
#, fuzzy
#| msgid "Barcode area"
msgid "Image area"
msgstr "QR-kode-område"
#: pretix/static/pretixcontrol/js/ui/editor.js:907
#: pretix/static/pretixcontrol/js/ui/editor.js:916
msgid "Powered by pretix"
msgstr "Drevet af pretix"
#: pretix/static/pretixcontrol/js/ui/editor.js:909
#: pretix/static/pretixcontrol/js/ui/editor.js:918
msgid "Object"
msgstr "Objekt"
#: pretix/static/pretixcontrol/js/ui/editor.js:913
#: pretix/static/pretixcontrol/js/ui/editor.js:922
msgid "Ticket design"
msgstr "Billetdesign"
#: pretix/static/pretixcontrol/js/ui/editor.js:1250
#: pretix/static/pretixcontrol/js/ui/editor.js:1258
msgid "Saving failed."
msgstr "Gem fejlede."
#: pretix/static/pretixcontrol/js/ui/editor.js:1319
#: pretix/static/pretixcontrol/js/ui/editor.js:1370
#: pretix/static/pretixcontrol/js/ui/editor.js:1327
#: pretix/static/pretixcontrol/js/ui/editor.js:1378
msgid "Error while uploading your PDF file, please try again."
msgstr "Fejl under upload af pdf. Prøv venligt igen."
#: pretix/static/pretixcontrol/js/ui/editor.js:1353
#: pretix/static/pretixcontrol/js/ui/editor.js:1361
msgid "Do you really want to leave the editor without saving your changes?"
msgstr ""
"Er du sikker på at du vil forlade editoren uden at gemme dine ændringer?"
@@ -656,54 +656,54 @@ msgstr "Opretter beskeder …"
msgid "Unknown error."
msgstr "Ukendt fejl."
#: pretix/static/pretixcontrol/js/ui/main.js:318
#: pretix/static/pretixcontrol/js/ui/main.js:330
msgid "Your color has great contrast and is very easy to read!"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:322
#: pretix/static/pretixcontrol/js/ui/main.js:334
msgid "Your color has decent contrast and is probably good-enough to read!"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:326
#: pretix/static/pretixcontrol/js/ui/main.js:338
msgid ""
"Your color has bad contrast for text on white background, please choose a "
"darker shade."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:442
#: pretix/static/pretixcontrol/js/ui/main.js:462
#: pretix/static/pretixcontrol/js/ui/main.js:454
#: pretix/static/pretixcontrol/js/ui/main.js:474
msgid "Search query"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:460
#: pretix/static/pretixcontrol/js/ui/main.js:472
msgid "All"
msgstr "Alle"
#: pretix/static/pretixcontrol/js/ui/main.js:461
#: pretix/static/pretixcontrol/js/ui/main.js:473
msgid "None"
msgstr "Ingen"
#: pretix/static/pretixcontrol/js/ui/main.js:465
#: pretix/static/pretixcontrol/js/ui/main.js:477
msgid "Selected only"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:808
#: pretix/static/pretixcontrol/js/ui/main.js:820
msgid "Enter page number between 1 and %(max)s."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:811
#: pretix/static/pretixcontrol/js/ui/main.js:823
msgid "Invalid page number."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:969
#: pretix/static/pretixcontrol/js/ui/main.js:981
msgid "Use a different name internally"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1009
#: pretix/static/pretixcontrol/js/ui/main.js:1021
msgid "Click to close"
msgstr "Klik for at lukke"
#: pretix/static/pretixcontrol/js/ui/main.js:1084
#: pretix/static/pretixcontrol/js/ui/main.js:1102
msgid "You have unsaved changes!"
msgstr "Du har ændringer, der ikke er gemt!"
@@ -713,6 +713,12 @@ msgstr "Du har ændringer, der ikke er gemt!"
msgid "Calculating default price…"
msgstr "Kontakter Stripe …"
#: pretix/static/pretixcontrol/js/ui/plugins.js:69
#, fuzzy
#| msgid "Search results"
msgid "No results"
msgstr "Søgeresultater"
#: pretix/static/pretixcontrol/js/ui/question.js:42
msgid "Others"
msgstr "Andre"
@@ -745,40 +751,40 @@ msgid_plural "The items in your cart are reserved for you for {num} minutes."
msgstr[0] "Varerne i din kurv er reserveret for dig i et minut."
msgstr[1] "Varerne i din kurv er reserveret for dig i {num} minutter."
#: pretix/static/pretixpresale/js/ui/main.js:203
#: pretix/static/pretixpresale/js/ui/main.js:215
#, fuzzy
#| msgctxt "widget"
#| msgid "from %(currency)s %(price)s"
msgid "The organizer keeps %(currency)s %(amount)s"
msgstr "fra %(currency)s %(price)s"
#: pretix/static/pretixpresale/js/ui/main.js:211
#: pretix/static/pretixpresale/js/ui/main.js:223
#, fuzzy
#| msgctxt "widget"
#| msgid "from %(currency)s %(price)s"
msgid "You get %(currency)s %(amount)s back"
msgstr "fra %(currency)s %(price)s"
#: pretix/static/pretixpresale/js/ui/main.js:227
#: pretix/static/pretixpresale/js/ui/main.js:239
msgid "Please enter the amount the organizer can keep."
msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:446
#: pretix/static/pretixpresale/js/ui/main.js:458
msgid "Please enter a quantity for one of the ticket types."
msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:498
#: pretix/static/pretixpresale/js/ui/main.js:510
#, fuzzy
#| msgid "Cart expired"
msgid "required"
msgstr "Kurv udløbet"
#: pretix/static/pretixpresale/js/ui/main.js:542
#: pretix/static/pretixpresale/js/ui/main.js:561
#: pretix/static/pretixpresale/js/ui/main.js:554
#: pretix/static/pretixpresale/js/ui/main.js:574
msgid "Time zone:"
msgstr "Tidszone:"
#: pretix/static/pretixpresale/js/ui/main.js:552
#: pretix/static/pretixpresale/js/ui/main.js:565
msgid "Your local time:"
msgstr "Din lokaltid:"
@@ -959,23 +965,31 @@ msgid "Open ticket shop"
msgstr "Luk billetbutik"
#: pretix/static/pretixpresale/js/widget/widget.js:48
#, fuzzy
#| msgctxt "widget"
#| msgid "Resume checkout"
msgctxt "widget"
msgid "Checkout"
msgstr "Fortsæt booking"
#: pretix/static/pretixpresale/js/widget/widget.js:49
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:49
#: pretix/static/pretixpresale/js/widget/widget.js:50
msgctxt "widget"
msgid ""
"We could not create your cart, since there are currently too many users in "
"this ticket shop. Please click \"Continue\" to retry in a new tab."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:51
#: pretix/static/pretixpresale/js/widget/widget.js:52
msgctxt "widget"
msgid "Waiting list"
msgstr "Venteliste"
#: pretix/static/pretixpresale/js/widget/widget.js:52
#: pretix/static/pretixpresale/js/widget/widget.js:53
msgctxt "widget"
msgid ""
"You currently have an active cart for this event. If you select more "
@@ -984,37 +998,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:54
#: pretix/static/pretixpresale/js/widget/widget.js:55
msgctxt "widget"
msgid "Resume checkout"
msgstr "Fortsæt booking"
#: pretix/static/pretixpresale/js/widget/widget.js:55
#: pretix/static/pretixpresale/js/widget/widget.js:56
msgctxt "widget"
msgid "Redeem a voucher"
msgstr "Indløs rabatkode"
#: pretix/static/pretixpresale/js/widget/widget.js:56
#: pretix/static/pretixpresale/js/widget/widget.js:57
msgctxt "widget"
msgid "Redeem"
msgstr "Indløs"
#: pretix/static/pretixpresale/js/widget/widget.js:57
#: pretix/static/pretixpresale/js/widget/widget.js:58
msgctxt "widget"
msgid "Voucher code"
msgstr "Rabatkode"
#: pretix/static/pretixpresale/js/widget/widget.js:58
#: pretix/static/pretixpresale/js/widget/widget.js:59
msgctxt "widget"
msgid "Close"
msgstr "Luk"
#: pretix/static/pretixpresale/js/widget/widget.js:59
#: pretix/static/pretixpresale/js/widget/widget.js:60
msgctxt "widget"
msgid "Continue"
msgstr "Fortsæt"
#: pretix/static/pretixpresale/js/widget/widget.js:60
#: pretix/static/pretixpresale/js/widget/widget.js:61
#, fuzzy
#| msgctxt "widget"
#| msgid "See variations"
@@ -1022,7 +1036,7 @@ msgctxt "widget"
msgid "Show variants"
msgstr "Vis varianter"
#: pretix/static/pretixpresale/js/widget/widget.js:61
#: pretix/static/pretixpresale/js/widget/widget.js:62
#, fuzzy
#| msgctxt "widget"
#| msgid "See variations"
@@ -1030,37 +1044,37 @@ msgctxt "widget"
msgid "Hide variants"
msgstr "Vis varianter"
#: pretix/static/pretixpresale/js/widget/widget.js:62
#: pretix/static/pretixpresale/js/widget/widget.js:63
msgctxt "widget"
msgid "Choose a different event"
msgstr "Vælg et andet arrangement"
#: pretix/static/pretixpresale/js/widget/widget.js:63
#: pretix/static/pretixpresale/js/widget/widget.js:64
msgctxt "widget"
msgid "Choose a different date"
msgstr "Vælg en anden dato"
#: pretix/static/pretixpresale/js/widget/widget.js:64
#: pretix/static/pretixpresale/js/widget/widget.js:65
msgctxt "widget"
msgid "Back"
msgstr "Tilbage"
#: pretix/static/pretixpresale/js/widget/widget.js:65
#: pretix/static/pretixpresale/js/widget/widget.js:66
msgctxt "widget"
msgid "Next month"
msgstr "Næste måned"
#: pretix/static/pretixpresale/js/widget/widget.js:66
#: pretix/static/pretixpresale/js/widget/widget.js:67
msgctxt "widget"
msgid "Previous month"
msgstr "Forrige måned"
#: pretix/static/pretixpresale/js/widget/widget.js:67
#: pretix/static/pretixpresale/js/widget/widget.js:68
msgctxt "widget"
msgid "Next week"
msgstr "Næste uge"
#: pretix/static/pretixpresale/js/widget/widget.js:68
#: pretix/static/pretixpresale/js/widget/widget.js:69
#, fuzzy
#| msgctxt "widget"
#| msgid "Previous month"
@@ -1068,12 +1082,12 @@ msgctxt "widget"
msgid "Previous week"
msgstr "Forrige måned"
#: pretix/static/pretixpresale/js/widget/widget.js:69
#: pretix/static/pretixpresale/js/widget/widget.js:70
msgctxt "widget"
msgid "Open seat selection"
msgstr "Åbn sædevalg"
#: pretix/static/pretixpresale/js/widget/widget.js:70
#: pretix/static/pretixpresale/js/widget/widget.js:71
msgctxt "widget"
msgid ""
"Some or all ticket categories are currently sold out. If you want, you can "
@@ -1081,84 +1095,112 @@ msgid ""
"again."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:71
#: pretix/static/pretixpresale/js/widget/widget.js:72
msgctxt "widget"
msgid "Load more"
msgstr "Hent flere"
#: pretix/static/pretixpresale/js/widget/widget.js:73
#: pretix/static/pretixpresale/js/widget/widget.js:74
msgid "Mo"
msgstr "Man"
#: pretix/static/pretixpresale/js/widget/widget.js:74
#: pretix/static/pretixpresale/js/widget/widget.js:75
msgid "Tu"
msgstr "Tirs"
#: pretix/static/pretixpresale/js/widget/widget.js:75
#: pretix/static/pretixpresale/js/widget/widget.js:76
msgid "We"
msgstr "Ons"
#: pretix/static/pretixpresale/js/widget/widget.js:76
#: pretix/static/pretixpresale/js/widget/widget.js:77
msgid "Th"
msgstr "Tors"
#: pretix/static/pretixpresale/js/widget/widget.js:77
#: pretix/static/pretixpresale/js/widget/widget.js:78
msgid "Fr"
msgstr "Fre"
#: pretix/static/pretixpresale/js/widget/widget.js:78
#: pretix/static/pretixpresale/js/widget/widget.js:79
msgid "Sa"
msgstr "Lør"
#: pretix/static/pretixpresale/js/widget/widget.js:79
#: pretix/static/pretixpresale/js/widget/widget.js:80
msgid "Su"
msgstr "Søn"
#: pretix/static/pretixpresale/js/widget/widget.js:81
msgid "Monday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:82
msgid "Tuesday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:83
msgid "Wednesday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:84
msgid "Thursday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:85
msgid "Friday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:86
msgid "Saturday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:87
msgid "Sunday"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:90
msgid "January"
msgstr "Januar"
#: pretix/static/pretixpresale/js/widget/widget.js:83
#: pretix/static/pretixpresale/js/widget/widget.js:91
msgid "February"
msgstr "Februar"
#: pretix/static/pretixpresale/js/widget/widget.js:84
#: pretix/static/pretixpresale/js/widget/widget.js:92
msgid "March"
msgstr "Marts"
#: pretix/static/pretixpresale/js/widget/widget.js:85
#: pretix/static/pretixpresale/js/widget/widget.js:93
msgid "April"
msgstr "April"
#: pretix/static/pretixpresale/js/widget/widget.js:86
#: pretix/static/pretixpresale/js/widget/widget.js:94
msgid "May"
msgstr "Maj"
#: pretix/static/pretixpresale/js/widget/widget.js:87
#: pretix/static/pretixpresale/js/widget/widget.js:95
msgid "June"
msgstr "Juni"
#: pretix/static/pretixpresale/js/widget/widget.js:88
#: pretix/static/pretixpresale/js/widget/widget.js:96
msgid "July"
msgstr "Juli"
#: pretix/static/pretixpresale/js/widget/widget.js:89
#: pretix/static/pretixpresale/js/widget/widget.js:97
msgid "August"
msgstr "August"
#: pretix/static/pretixpresale/js/widget/widget.js:90
#: pretix/static/pretixpresale/js/widget/widget.js:98
msgid "September"
msgstr "September"
#: pretix/static/pretixpresale/js/widget/widget.js:91
#: pretix/static/pretixpresale/js/widget/widget.js:99
msgid "October"
msgstr "Oktober"
#: pretix/static/pretixpresale/js/widget/widget.js:92
#: pretix/static/pretixpresale/js/widget/widget.js:100
msgid "November"
msgstr "November"
#: pretix/static/pretixpresale/js/widget/widget.js:93
#: pretix/static/pretixpresale/js/widget/widget.js:101
msgid "December"
msgstr "December"
File diff suppressed because it is too large Load Diff
+114 -77
View File
@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-01-29 13:18+0000\n"
"PO-Revision-Date: 2025-01-22 16:00+0000\n"
"POT-Creation-Date: 2025-04-28 11:08+0000\n"
"PO-Revision-Date: 2025-04-28 11:32+0000\n"
"Last-Translator: Raphael Michel <michel@rami.io>\n"
"Language-Team: German <https://translate.pretix.eu/projects/pretix/pretix-js/"
"de/>\n"
@@ -17,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.9.2\n"
"X-Generator: Weblate 5.11\n"
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
@@ -563,53 +563,53 @@ msgstr "abwesend"
msgid "Check-in QR"
msgstr "Check-in-QR-Code"
#: pretix/static/pretixcontrol/js/ui/editor.js:543
#: pretix/static/pretixcontrol/js/ui/editor.js:549
msgid "The PDF background file could not be loaded for the following reason:"
msgstr "Die Hintergrund-PDF-Datei konnte nicht geladen werden:"
#: pretix/static/pretixcontrol/js/ui/editor.js:894
#: pretix/static/pretixcontrol/js/ui/editor.js:903
msgid "Group of objects"
msgstr "Gruppe von Objekten"
#: pretix/static/pretixcontrol/js/ui/editor.js:899
#: pretix/static/pretixcontrol/js/ui/editor.js:908
msgid "Text object (deprecated)"
msgstr "Text-Objekt (veraltet)"
#: pretix/static/pretixcontrol/js/ui/editor.js:901
#: pretix/static/pretixcontrol/js/ui/editor.js:910
msgid "Text box"
msgstr "Textbox"
#: pretix/static/pretixcontrol/js/ui/editor.js:903
#: pretix/static/pretixcontrol/js/ui/editor.js:912
msgid "Barcode area"
msgstr "QR-Code-Bereich"
#: pretix/static/pretixcontrol/js/ui/editor.js:905
#: pretix/static/pretixcontrol/js/ui/editor.js:914
msgid "Image area"
msgstr "Bildbereich"
#: pretix/static/pretixcontrol/js/ui/editor.js:907
#: pretix/static/pretixcontrol/js/ui/editor.js:916
msgid "Powered by pretix"
msgstr "Event-Ticketshop von pretix"
#: pretix/static/pretixcontrol/js/ui/editor.js:909
#: pretix/static/pretixcontrol/js/ui/editor.js:918
msgid "Object"
msgstr "Objekt"
#: pretix/static/pretixcontrol/js/ui/editor.js:913
#: pretix/static/pretixcontrol/js/ui/editor.js:922
msgid "Ticket design"
msgstr "Ticket-Design"
#: pretix/static/pretixcontrol/js/ui/editor.js:1250
#: pretix/static/pretixcontrol/js/ui/editor.js:1258
msgid "Saving failed."
msgstr "Speichern fehlgeschlagen."
#: pretix/static/pretixcontrol/js/ui/editor.js:1319
#: pretix/static/pretixcontrol/js/ui/editor.js:1370
#: pretix/static/pretixcontrol/js/ui/editor.js:1327
#: pretix/static/pretixcontrol/js/ui/editor.js:1378
msgid "Error while uploading your PDF file, please try again."
msgstr ""
"Es gab ein Problem beim Hochladen der PDF-Datei, bitte erneut versuchen."
#: pretix/static/pretixcontrol/js/ui/editor.js:1353
#: pretix/static/pretixcontrol/js/ui/editor.js:1361
msgid "Do you really want to leave the editor without saving your changes?"
msgstr ""
"Möchten Sie den Editor wirklich schließen ohne Ihre Änderungen zu speichern?"
@@ -626,17 +626,17 @@ msgstr "Generiere Nachrichten…"
msgid "Unknown error."
msgstr "Unbekannter Fehler."
#: pretix/static/pretixcontrol/js/ui/main.js:318
#: pretix/static/pretixcontrol/js/ui/main.js:330
msgid "Your color has great contrast and is very easy to read!"
msgstr "Diese Farbe hat einen sehr guten Kontrast und ist sehr gut zu lesen!"
#: pretix/static/pretixcontrol/js/ui/main.js:322
#: pretix/static/pretixcontrol/js/ui/main.js:334
msgid "Your color has decent contrast and is probably good-enough to read!"
msgstr ""
"Diese Farbe hat einen ausreichenden Kontrast und ist wahrscheinlich gut zu "
"lesen!"
#: pretix/static/pretixcontrol/js/ui/main.js:326
#: pretix/static/pretixcontrol/js/ui/main.js:338
msgid ""
"Your color has bad contrast for text on white background, please choose a "
"darker shade."
@@ -644,40 +644,40 @@ msgstr ""
"Diese Farbe hat einen schlechten Kontrast für Text auf einem weißen "
"Hintergrund. Bitte wählen Sie eine dunklere Farbe."
#: pretix/static/pretixcontrol/js/ui/main.js:442
#: pretix/static/pretixcontrol/js/ui/main.js:462
#: pretix/static/pretixcontrol/js/ui/main.js:454
#: pretix/static/pretixcontrol/js/ui/main.js:474
msgid "Search query"
msgstr "Suchbegriff"
#: pretix/static/pretixcontrol/js/ui/main.js:460
#: pretix/static/pretixcontrol/js/ui/main.js:472
msgid "All"
msgstr "Alle"
#: pretix/static/pretixcontrol/js/ui/main.js:461
#: pretix/static/pretixcontrol/js/ui/main.js:473
msgid "None"
msgstr "Keine"
#: pretix/static/pretixcontrol/js/ui/main.js:465
#: pretix/static/pretixcontrol/js/ui/main.js:477
msgid "Selected only"
msgstr "Nur ausgewählte"
#: pretix/static/pretixcontrol/js/ui/main.js:808
#: pretix/static/pretixcontrol/js/ui/main.js:820
msgid "Enter page number between 1 and %(max)s."
msgstr "Geben Sie eine Seitenzahl zwischen 1 und %(max)s ein."
#: pretix/static/pretixcontrol/js/ui/main.js:811
#: pretix/static/pretixcontrol/js/ui/main.js:823
msgid "Invalid page number."
msgstr "Ungültige Seitenzahl."
#: pretix/static/pretixcontrol/js/ui/main.js:969
#: pretix/static/pretixcontrol/js/ui/main.js:981
msgid "Use a different name internally"
msgstr "Intern einen anderen Namen verwenden"
#: pretix/static/pretixcontrol/js/ui/main.js:1009
#: pretix/static/pretixcontrol/js/ui/main.js:1021
msgid "Click to close"
msgstr "Klicken zum Schließen"
#: pretix/static/pretixcontrol/js/ui/main.js:1084
#: pretix/static/pretixcontrol/js/ui/main.js:1102
msgid "You have unsaved changes!"
msgstr "Sie haben ungespeicherte Änderungen!"
@@ -685,6 +685,10 @@ msgstr "Sie haben ungespeicherte Änderungen!"
msgid "Calculating default price…"
msgstr "Berechne Standardpreis…"
#: pretix/static/pretixcontrol/js/ui/plugins.js:69
msgid "No results"
msgstr "Keine Ergebnisse"
#: pretix/static/pretixcontrol/js/ui/question.js:42
msgid "Others"
msgstr "Sonstige"
@@ -720,32 +724,32 @@ msgstr[0] ""
msgstr[1] ""
"Die Produkte in Ihrem Warenkorb sind noch {num} Minuten für Sie reserviert."
#: pretix/static/pretixpresale/js/ui/main.js:203
#: pretix/static/pretixpresale/js/ui/main.js:215
msgid "The organizer keeps %(currency)s %(amount)s"
msgstr "Der Veranstalter behält %(currency)s %(amount)s ein"
#: pretix/static/pretixpresale/js/ui/main.js:211
#: pretix/static/pretixpresale/js/ui/main.js:223
msgid "You get %(currency)s %(amount)s back"
msgstr "Sie erhalten %(currency)s %(amount)s zurück"
#: pretix/static/pretixpresale/js/ui/main.js:227
#: pretix/static/pretixpresale/js/ui/main.js:239
msgid "Please enter the amount the organizer can keep."
msgstr "Bitte geben Sie den Betrag ein, den der Veranstalter einbehalten darf."
#: pretix/static/pretixpresale/js/ui/main.js:446
#: pretix/static/pretixpresale/js/ui/main.js:458
msgid "Please enter a quantity for one of the ticket types."
msgstr "Bitte tragen Sie eine Menge für eines der Produkte ein."
#: pretix/static/pretixpresale/js/ui/main.js:498
#: pretix/static/pretixpresale/js/ui/main.js:510
msgid "required"
msgstr "verpflichtend"
#: pretix/static/pretixpresale/js/ui/main.js:542
#: pretix/static/pretixpresale/js/ui/main.js:561
#: pretix/static/pretixpresale/js/ui/main.js:554
#: pretix/static/pretixpresale/js/ui/main.js:574
msgid "Time zone:"
msgstr "Zeitzone:"
#: pretix/static/pretixpresale/js/ui/main.js:552
#: pretix/static/pretixpresale/js/ui/main.js:565
msgid "Your local time:"
msgstr "Deine lokale Zeit:"
@@ -917,10 +921,15 @@ msgstr "Ticketshop öffnen"
#: pretix/static/pretixpresale/js/widget/widget.js:48
msgctxt "widget"
msgid "Checkout"
msgstr "Buchung"
#: pretix/static/pretixpresale/js/widget/widget.js:49
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:49
#: pretix/static/pretixpresale/js/widget/widget.js:50
msgctxt "widget"
msgid ""
"We could not create your cart, since there are currently too many users in "
@@ -930,12 +939,12 @@ msgstr ""
"diesem Ticketshop sind. Bitte klicken Sie \"Weiter\" um es in einem neuen "
"Tab erneut zu versuchen."
#: pretix/static/pretixpresale/js/widget/widget.js:51
#: pretix/static/pretixpresale/js/widget/widget.js:52
msgctxt "widget"
msgid "Waiting list"
msgstr "Warteliste"
#: pretix/static/pretixpresale/js/widget/widget.js:52
#: pretix/static/pretixpresale/js/widget/widget.js:53
msgctxt "widget"
msgid ""
"You currently have an active cart for this event. If you select more "
@@ -944,87 +953,87 @@ 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:54
#: pretix/static/pretixpresale/js/widget/widget.js:55
msgctxt "widget"
msgid "Resume checkout"
msgstr "Kauf fortsetzen"
#: pretix/static/pretixpresale/js/widget/widget.js:55
#: pretix/static/pretixpresale/js/widget/widget.js:56
msgctxt "widget"
msgid "Redeem a voucher"
msgstr "Gutschein einlösen"
#: pretix/static/pretixpresale/js/widget/widget.js:56
#: pretix/static/pretixpresale/js/widget/widget.js:57
msgctxt "widget"
msgid "Redeem"
msgstr "Einlösen"
#: pretix/static/pretixpresale/js/widget/widget.js:57
#: pretix/static/pretixpresale/js/widget/widget.js:58
msgctxt "widget"
msgid "Voucher code"
msgstr "Gutscheincode"
#: pretix/static/pretixpresale/js/widget/widget.js:58
#: pretix/static/pretixpresale/js/widget/widget.js:59
msgctxt "widget"
msgid "Close"
msgstr "Schließen"
#: pretix/static/pretixpresale/js/widget/widget.js:59
#: pretix/static/pretixpresale/js/widget/widget.js:60
msgctxt "widget"
msgid "Continue"
msgstr "Fortfahren"
#: pretix/static/pretixpresale/js/widget/widget.js:60
#: pretix/static/pretixpresale/js/widget/widget.js:61
msgctxt "widget"
msgid "Show variants"
msgstr "Varianten zeigen"
#: pretix/static/pretixpresale/js/widget/widget.js:61
#: pretix/static/pretixpresale/js/widget/widget.js:62
msgctxt "widget"
msgid "Hide variants"
msgstr "Varianten verstecken"
#: pretix/static/pretixpresale/js/widget/widget.js:62
#: pretix/static/pretixpresale/js/widget/widget.js:63
msgctxt "widget"
msgid "Choose a different event"
msgstr "Andere Veranstaltung auswählen"
#: pretix/static/pretixpresale/js/widget/widget.js:63
#: pretix/static/pretixpresale/js/widget/widget.js:64
msgctxt "widget"
msgid "Choose a different date"
msgstr "Anderen Termin auswählen"
#: pretix/static/pretixpresale/js/widget/widget.js:64
#: pretix/static/pretixpresale/js/widget/widget.js:65
msgctxt "widget"
msgid "Back"
msgstr "Zurück"
#: pretix/static/pretixpresale/js/widget/widget.js:65
#: pretix/static/pretixpresale/js/widget/widget.js:66
msgctxt "widget"
msgid "Next month"
msgstr "Nächster Monat"
#: pretix/static/pretixpresale/js/widget/widget.js:66
#: pretix/static/pretixpresale/js/widget/widget.js:67
msgctxt "widget"
msgid "Previous month"
msgstr "Vorheriger Monat"
#: pretix/static/pretixpresale/js/widget/widget.js:67
#: pretix/static/pretixpresale/js/widget/widget.js:68
msgctxt "widget"
msgid "Next week"
msgstr "Nächste Woche"
#: pretix/static/pretixpresale/js/widget/widget.js:68
#: pretix/static/pretixpresale/js/widget/widget.js:69
msgctxt "widget"
msgid "Previous week"
msgstr "Vorherige Woche"
#: pretix/static/pretixpresale/js/widget/widget.js:69
#: pretix/static/pretixpresale/js/widget/widget.js:70
msgctxt "widget"
msgid "Open seat selection"
msgstr "Saalplan öffnen"
msgstr "Sitzplan öffnen"
#: pretix/static/pretixpresale/js/widget/widget.js:70
#: pretix/static/pretixpresale/js/widget/widget.js:71
msgctxt "widget"
msgid ""
"Some or all ticket categories are currently sold out. If you want, you can "
@@ -1035,84 +1044,112 @@ 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:71
#: pretix/static/pretixpresale/js/widget/widget.js:72
msgctxt "widget"
msgid "Load more"
msgstr "Mehr laden"
#: pretix/static/pretixpresale/js/widget/widget.js:73
#: pretix/static/pretixpresale/js/widget/widget.js:74
msgid "Mo"
msgstr "Mo"
#: pretix/static/pretixpresale/js/widget/widget.js:74
#: pretix/static/pretixpresale/js/widget/widget.js:75
msgid "Tu"
msgstr "Di"
#: pretix/static/pretixpresale/js/widget/widget.js:75
#: pretix/static/pretixpresale/js/widget/widget.js:76
msgid "We"
msgstr "Mi"
#: pretix/static/pretixpresale/js/widget/widget.js:76
#: pretix/static/pretixpresale/js/widget/widget.js:77
msgid "Th"
msgstr "Do"
#: pretix/static/pretixpresale/js/widget/widget.js:77
#: pretix/static/pretixpresale/js/widget/widget.js:78
msgid "Fr"
msgstr "Fr"
#: pretix/static/pretixpresale/js/widget/widget.js:78
#: pretix/static/pretixpresale/js/widget/widget.js:79
msgid "Sa"
msgstr "Sa"
#: pretix/static/pretixpresale/js/widget/widget.js:79
#: pretix/static/pretixpresale/js/widget/widget.js:80
msgid "Su"
msgstr "So"
#: pretix/static/pretixpresale/js/widget/widget.js:81
msgid "Monday"
msgstr "Montag"
#: pretix/static/pretixpresale/js/widget/widget.js:82
msgid "Tuesday"
msgstr "Dienstag"
#: pretix/static/pretixpresale/js/widget/widget.js:83
msgid "Wednesday"
msgstr "Mittwoch"
#: pretix/static/pretixpresale/js/widget/widget.js:84
msgid "Thursday"
msgstr "Donnerstag"
#: pretix/static/pretixpresale/js/widget/widget.js:85
msgid "Friday"
msgstr "Freitag"
#: pretix/static/pretixpresale/js/widget/widget.js:86
msgid "Saturday"
msgstr "Samstag"
#: pretix/static/pretixpresale/js/widget/widget.js:87
msgid "Sunday"
msgstr "Sonntag"
#: pretix/static/pretixpresale/js/widget/widget.js:90
msgid "January"
msgstr "Januar"
#: pretix/static/pretixpresale/js/widget/widget.js:83
#: pretix/static/pretixpresale/js/widget/widget.js:91
msgid "February"
msgstr "Februar"
#: pretix/static/pretixpresale/js/widget/widget.js:84
#: pretix/static/pretixpresale/js/widget/widget.js:92
msgid "March"
msgstr "März"
#: pretix/static/pretixpresale/js/widget/widget.js:85
#: pretix/static/pretixpresale/js/widget/widget.js:93
msgid "April"
msgstr "April"
#: pretix/static/pretixpresale/js/widget/widget.js:86
#: pretix/static/pretixpresale/js/widget/widget.js:94
msgid "May"
msgstr "Mai"
#: pretix/static/pretixpresale/js/widget/widget.js:87
#: pretix/static/pretixpresale/js/widget/widget.js:95
msgid "June"
msgstr "Juni"
#: pretix/static/pretixpresale/js/widget/widget.js:88
#: pretix/static/pretixpresale/js/widget/widget.js:96
msgid "July"
msgstr "Juli"
#: pretix/static/pretixpresale/js/widget/widget.js:89
#: pretix/static/pretixpresale/js/widget/widget.js:97
msgid "August"
msgstr "August"
#: pretix/static/pretixpresale/js/widget/widget.js:90
#: pretix/static/pretixpresale/js/widget/widget.js:98
msgid "September"
msgstr "September"
#: pretix/static/pretixpresale/js/widget/widget.js:91
#: pretix/static/pretixpresale/js/widget/widget.js:99
msgid "October"
msgstr "Oktober"
#: pretix/static/pretixpresale/js/widget/widget.js:92
#: pretix/static/pretixpresale/js/widget/widget.js:100
msgid "November"
msgstr "November"
#: pretix/static/pretixpresale/js/widget/widget.js:93
#: pretix/static/pretixpresale/js/widget/widget.js:101
msgid "December"
msgstr "Dezember"
+4 -1
View File
@@ -30,7 +30,8 @@ Auth
Authentication
Authenticator
Authentifizierungsmechanismus
Authorisierungscode
Autorisierungs
Autorisierungscode
Backend
Badge
Badges
@@ -235,6 +236,7 @@ PayPals
PayU
PCI
Personalisierung
PKCE
Platzhalterzeichen
Play
Plugin
@@ -254,6 +256,7 @@ Professional
Przelewy
pt
px
Query
QR
rabattiert
Rabattierung
File diff suppressed because it is too large Load Diff
@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-01-29 13:18+0000\n"
"PO-Revision-Date: 2025-01-22 16:00+0000\n"
"POT-Creation-Date: 2025-04-28 11:08+0000\n"
"PO-Revision-Date: 2025-04-28 12:21+0000\n"
"Last-Translator: Raphael Michel <michel@rami.io>\n"
"Language-Team: German (informal) <https://translate.pretix.eu/projects/"
"pretix/pretix-js/de_Informal/>\n"
@@ -17,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.9.2\n"
"X-Generator: Weblate 5.11\n"
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
@@ -562,53 +562,53 @@ msgstr "abwesend"
msgid "Check-in QR"
msgstr "Check-in-QR-Code"
#: pretix/static/pretixcontrol/js/ui/editor.js:543
#: pretix/static/pretixcontrol/js/ui/editor.js:549
msgid "The PDF background file could not be loaded for the following reason:"
msgstr "Die Hintergrund-PDF-Datei konnte nicht geladen werden:"
#: pretix/static/pretixcontrol/js/ui/editor.js:894
#: pretix/static/pretixcontrol/js/ui/editor.js:903
msgid "Group of objects"
msgstr "Gruppe von Objekten"
#: pretix/static/pretixcontrol/js/ui/editor.js:899
#: pretix/static/pretixcontrol/js/ui/editor.js:908
msgid "Text object (deprecated)"
msgstr "Text-Objekt (veraltet)"
#: pretix/static/pretixcontrol/js/ui/editor.js:901
#: pretix/static/pretixcontrol/js/ui/editor.js:910
msgid "Text box"
msgstr "Textbox"
#: pretix/static/pretixcontrol/js/ui/editor.js:903
#: pretix/static/pretixcontrol/js/ui/editor.js:912
msgid "Barcode area"
msgstr "QR-Code-Bereich"
#: pretix/static/pretixcontrol/js/ui/editor.js:905
#: pretix/static/pretixcontrol/js/ui/editor.js:914
msgid "Image area"
msgstr "Bildbereich"
#: pretix/static/pretixcontrol/js/ui/editor.js:907
#: pretix/static/pretixcontrol/js/ui/editor.js:916
msgid "Powered by pretix"
msgstr "Event-Ticketshop von pretix"
#: pretix/static/pretixcontrol/js/ui/editor.js:909
#: pretix/static/pretixcontrol/js/ui/editor.js:918
msgid "Object"
msgstr "Objekt"
#: pretix/static/pretixcontrol/js/ui/editor.js:913
#: pretix/static/pretixcontrol/js/ui/editor.js:922
msgid "Ticket design"
msgstr "Ticket-Design"
#: pretix/static/pretixcontrol/js/ui/editor.js:1250
#: pretix/static/pretixcontrol/js/ui/editor.js:1258
msgid "Saving failed."
msgstr "Speichern fehlgeschlagen."
#: pretix/static/pretixcontrol/js/ui/editor.js:1319
#: pretix/static/pretixcontrol/js/ui/editor.js:1370
#: pretix/static/pretixcontrol/js/ui/editor.js:1327
#: pretix/static/pretixcontrol/js/ui/editor.js:1378
msgid "Error while uploading your PDF file, please try again."
msgstr ""
"Es gab ein Problem beim Hochladen der PDF-Datei, bitte erneut versuchen."
#: pretix/static/pretixcontrol/js/ui/editor.js:1353
#: pretix/static/pretixcontrol/js/ui/editor.js:1361
msgid "Do you really want to leave the editor without saving your changes?"
msgstr ""
"Möchtest du den Editor wirklich schließen ohne Ihre Änderungen zu speichern?"
@@ -625,17 +625,17 @@ msgstr "Generiere Nachrichten…"
msgid "Unknown error."
msgstr "Unbekannter Fehler."
#: pretix/static/pretixcontrol/js/ui/main.js:318
#: pretix/static/pretixcontrol/js/ui/main.js:330
msgid "Your color has great contrast and is very easy to read!"
msgstr "Diese Farbe hat einen sehr guten Kontrast und ist sehr gut zu lesen!"
#: pretix/static/pretixcontrol/js/ui/main.js:322
#: pretix/static/pretixcontrol/js/ui/main.js:334
msgid "Your color has decent contrast and is probably good-enough to read!"
msgstr ""
"Diese Farbe hat einen ausreichenden Kontrast und ist wahrscheinlich gut zu "
"lesen!"
#: pretix/static/pretixcontrol/js/ui/main.js:326
#: pretix/static/pretixcontrol/js/ui/main.js:338
msgid ""
"Your color has bad contrast for text on white background, please choose a "
"darker shade."
@@ -643,40 +643,40 @@ msgstr ""
"Diese Farbe hat einen schlechten Kontrast für Text auf einem weißen "
"Hintergrund. Bitte wähle eine dunklere Farbe."
#: pretix/static/pretixcontrol/js/ui/main.js:442
#: pretix/static/pretixcontrol/js/ui/main.js:462
#: pretix/static/pretixcontrol/js/ui/main.js:454
#: pretix/static/pretixcontrol/js/ui/main.js:474
msgid "Search query"
msgstr "Suchbegriff"
#: pretix/static/pretixcontrol/js/ui/main.js:460
#: pretix/static/pretixcontrol/js/ui/main.js:472
msgid "All"
msgstr "Alle"
#: pretix/static/pretixcontrol/js/ui/main.js:461
#: pretix/static/pretixcontrol/js/ui/main.js:473
msgid "None"
msgstr "Keine"
#: pretix/static/pretixcontrol/js/ui/main.js:465
#: pretix/static/pretixcontrol/js/ui/main.js:477
msgid "Selected only"
msgstr "Nur ausgewählte"
#: pretix/static/pretixcontrol/js/ui/main.js:808
#: pretix/static/pretixcontrol/js/ui/main.js:820
msgid "Enter page number between 1 and %(max)s."
msgstr "Gib eine Seitenzahl zwischen 1 und %(max)s ein."
#: pretix/static/pretixcontrol/js/ui/main.js:811
#: pretix/static/pretixcontrol/js/ui/main.js:823
msgid "Invalid page number."
msgstr "Ungültige Seitenzahl."
#: pretix/static/pretixcontrol/js/ui/main.js:969
#: pretix/static/pretixcontrol/js/ui/main.js:981
msgid "Use a different name internally"
msgstr "Intern einen anderen Namen verwenden"
#: pretix/static/pretixcontrol/js/ui/main.js:1009
#: pretix/static/pretixcontrol/js/ui/main.js:1021
msgid "Click to close"
msgstr "Klicken zum Schließen"
#: pretix/static/pretixcontrol/js/ui/main.js:1084
#: pretix/static/pretixcontrol/js/ui/main.js:1102
msgid "You have unsaved changes!"
msgstr "Du hast ungespeicherte Änderungen!"
@@ -684,6 +684,10 @@ msgstr "Du hast ungespeicherte Änderungen!"
msgid "Calculating default price…"
msgstr "Berechne Standardpreis…"
#: pretix/static/pretixcontrol/js/ui/plugins.js:69
msgid "No results"
msgstr "Keine Ergebnisse"
#: pretix/static/pretixcontrol/js/ui/question.js:42
msgid "Others"
msgstr "Sonstige"
@@ -719,32 +723,32 @@ msgstr[0] ""
msgstr[1] ""
"Die Produkte in deinem Warenkorb sind noch {num} Minuten für dich reserviert."
#: pretix/static/pretixpresale/js/ui/main.js:203
#: pretix/static/pretixpresale/js/ui/main.js:215
msgid "The organizer keeps %(currency)s %(amount)s"
msgstr "Der Veranstalter behält %(currency)s %(amount)s ein"
#: pretix/static/pretixpresale/js/ui/main.js:211
#: pretix/static/pretixpresale/js/ui/main.js:223
msgid "You get %(currency)s %(amount)s back"
msgstr "Du erhältst %(currency)s %(amount)s zurück"
#: pretix/static/pretixpresale/js/ui/main.js:227
#: pretix/static/pretixpresale/js/ui/main.js:239
msgid "Please enter the amount the organizer can keep."
msgstr "Bitte gib den Betrag ein, den der Veranstalter einbehalten darf."
#: pretix/static/pretixpresale/js/ui/main.js:446
#: pretix/static/pretixpresale/js/ui/main.js:458
msgid "Please enter a quantity for one of the ticket types."
msgstr "Bitte trage eine Menge für eines der Produkte ein."
#: pretix/static/pretixpresale/js/ui/main.js:498
#: pretix/static/pretixpresale/js/ui/main.js:510
msgid "required"
msgstr "verpflichtend"
#: pretix/static/pretixpresale/js/ui/main.js:542
#: pretix/static/pretixpresale/js/ui/main.js:561
#: pretix/static/pretixpresale/js/ui/main.js:554
#: pretix/static/pretixpresale/js/ui/main.js:574
msgid "Time zone:"
msgstr "Zeitzone:"
#: pretix/static/pretixpresale/js/ui/main.js:552
#: pretix/static/pretixpresale/js/ui/main.js:565
msgid "Your local time:"
msgstr "Deine lokale Zeit:"
@@ -916,10 +920,15 @@ msgstr "Ticketshop öffnen"
#: pretix/static/pretixpresale/js/widget/widget.js:48
msgctxt "widget"
msgid "Checkout"
msgstr "Buchung"
#: pretix/static/pretixpresale/js/widget/widget.js:49
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:49
#: pretix/static/pretixpresale/js/widget/widget.js:50
msgctxt "widget"
msgid ""
"We could not create your cart, since there are currently too many users in "
@@ -929,12 +938,12 @@ msgstr ""
"diesem Ticketshop sind. Bitte klicke \"Weiter\" um es in einem neuen Tab "
"erneut zu versuchen."
#: pretix/static/pretixpresale/js/widget/widget.js:51
#: pretix/static/pretixpresale/js/widget/widget.js:52
msgctxt "widget"
msgid "Waiting list"
msgstr "Warteliste"
#: pretix/static/pretixpresale/js/widget/widget.js:52
#: pretix/static/pretixpresale/js/widget/widget.js:53
msgctxt "widget"
msgid ""
"You currently have an active cart for this event. If you select more "
@@ -943,87 +952,87 @@ 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:54
#: pretix/static/pretixpresale/js/widget/widget.js:55
msgctxt "widget"
msgid "Resume checkout"
msgstr "Kauf fortsetzen"
#: pretix/static/pretixpresale/js/widget/widget.js:55
#: pretix/static/pretixpresale/js/widget/widget.js:56
msgctxt "widget"
msgid "Redeem a voucher"
msgstr "Gutschein einlösen"
#: pretix/static/pretixpresale/js/widget/widget.js:56
#: pretix/static/pretixpresale/js/widget/widget.js:57
msgctxt "widget"
msgid "Redeem"
msgstr "Einlösen"
#: pretix/static/pretixpresale/js/widget/widget.js:57
#: pretix/static/pretixpresale/js/widget/widget.js:58
msgctxt "widget"
msgid "Voucher code"
msgstr "Gutscheincode"
#: pretix/static/pretixpresale/js/widget/widget.js:58
#: pretix/static/pretixpresale/js/widget/widget.js:59
msgctxt "widget"
msgid "Close"
msgstr "Schließen"
#: pretix/static/pretixpresale/js/widget/widget.js:59
#: pretix/static/pretixpresale/js/widget/widget.js:60
msgctxt "widget"
msgid "Continue"
msgstr "Fortfahren"
#: pretix/static/pretixpresale/js/widget/widget.js:60
#: pretix/static/pretixpresale/js/widget/widget.js:61
msgctxt "widget"
msgid "Show variants"
msgstr "Varianten zeigen"
#: pretix/static/pretixpresale/js/widget/widget.js:61
#: pretix/static/pretixpresale/js/widget/widget.js:62
msgctxt "widget"
msgid "Hide variants"
msgstr "Varianten verstecken"
#: pretix/static/pretixpresale/js/widget/widget.js:62
#: pretix/static/pretixpresale/js/widget/widget.js:63
msgctxt "widget"
msgid "Choose a different event"
msgstr "Andere Veranstaltung auswählen"
#: pretix/static/pretixpresale/js/widget/widget.js:63
#: pretix/static/pretixpresale/js/widget/widget.js:64
msgctxt "widget"
msgid "Choose a different date"
msgstr "Anderen Termin auswählen"
#: pretix/static/pretixpresale/js/widget/widget.js:64
#: pretix/static/pretixpresale/js/widget/widget.js:65
msgctxt "widget"
msgid "Back"
msgstr "Zurück"
#: pretix/static/pretixpresale/js/widget/widget.js:65
#: pretix/static/pretixpresale/js/widget/widget.js:66
msgctxt "widget"
msgid "Next month"
msgstr "Nächster Monat"
#: pretix/static/pretixpresale/js/widget/widget.js:66
#: pretix/static/pretixpresale/js/widget/widget.js:67
msgctxt "widget"
msgid "Previous month"
msgstr "Vorheriger Monat"
#: pretix/static/pretixpresale/js/widget/widget.js:67
#: pretix/static/pretixpresale/js/widget/widget.js:68
msgctxt "widget"
msgid "Next week"
msgstr "Nächste Woche"
#: pretix/static/pretixpresale/js/widget/widget.js:68
#: pretix/static/pretixpresale/js/widget/widget.js:69
msgctxt "widget"
msgid "Previous week"
msgstr "Vorherige Woche"
#: pretix/static/pretixpresale/js/widget/widget.js:69
#: pretix/static/pretixpresale/js/widget/widget.js:70
msgctxt "widget"
msgid "Open seat selection"
msgstr "Saalplan öffnen"
msgstr "Sitzplan öffnen"
#: pretix/static/pretixpresale/js/widget/widget.js:70
#: pretix/static/pretixpresale/js/widget/widget.js:71
msgctxt "widget"
msgid ""
"Some or all ticket categories are currently sold out. If you want, you can "
@@ -1034,84 +1043,112 @@ 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:71
#: pretix/static/pretixpresale/js/widget/widget.js:72
msgctxt "widget"
msgid "Load more"
msgstr "Mehr laden"
#: pretix/static/pretixpresale/js/widget/widget.js:73
#: pretix/static/pretixpresale/js/widget/widget.js:74
msgid "Mo"
msgstr "Mo"
#: pretix/static/pretixpresale/js/widget/widget.js:74
#: pretix/static/pretixpresale/js/widget/widget.js:75
msgid "Tu"
msgstr "Di"
#: pretix/static/pretixpresale/js/widget/widget.js:75
#: pretix/static/pretixpresale/js/widget/widget.js:76
msgid "We"
msgstr "Mi"
#: pretix/static/pretixpresale/js/widget/widget.js:76
#: pretix/static/pretixpresale/js/widget/widget.js:77
msgid "Th"
msgstr "Do"
#: pretix/static/pretixpresale/js/widget/widget.js:77
#: pretix/static/pretixpresale/js/widget/widget.js:78
msgid "Fr"
msgstr "Fr"
#: pretix/static/pretixpresale/js/widget/widget.js:78
#: pretix/static/pretixpresale/js/widget/widget.js:79
msgid "Sa"
msgstr "Sa"
#: pretix/static/pretixpresale/js/widget/widget.js:79
#: pretix/static/pretixpresale/js/widget/widget.js:80
msgid "Su"
msgstr "So"
#: pretix/static/pretixpresale/js/widget/widget.js:81
msgid "Monday"
msgstr "Montag"
#: pretix/static/pretixpresale/js/widget/widget.js:82
msgid "Tuesday"
msgstr "Dienstag"
#: pretix/static/pretixpresale/js/widget/widget.js:83
msgid "Wednesday"
msgstr "Mittwoch"
#: pretix/static/pretixpresale/js/widget/widget.js:84
msgid "Thursday"
msgstr "Donnerstag"
#: pretix/static/pretixpresale/js/widget/widget.js:85
msgid "Friday"
msgstr "Freitag"
#: pretix/static/pretixpresale/js/widget/widget.js:86
msgid "Saturday"
msgstr "Samstag"
#: pretix/static/pretixpresale/js/widget/widget.js:87
msgid "Sunday"
msgstr "Sonntag"
#: pretix/static/pretixpresale/js/widget/widget.js:90
msgid "January"
msgstr "Januar"
#: pretix/static/pretixpresale/js/widget/widget.js:83
#: pretix/static/pretixpresale/js/widget/widget.js:91
msgid "February"
msgstr "Februar"
#: pretix/static/pretixpresale/js/widget/widget.js:84
#: pretix/static/pretixpresale/js/widget/widget.js:92
msgid "March"
msgstr "März"
#: pretix/static/pretixpresale/js/widget/widget.js:85
#: pretix/static/pretixpresale/js/widget/widget.js:93
msgid "April"
msgstr "April"
#: pretix/static/pretixpresale/js/widget/widget.js:86
#: pretix/static/pretixpresale/js/widget/widget.js:94
msgid "May"
msgstr "Mai"
#: pretix/static/pretixpresale/js/widget/widget.js:87
#: pretix/static/pretixpresale/js/widget/widget.js:95
msgid "June"
msgstr "Juni"
#: pretix/static/pretixpresale/js/widget/widget.js:88
#: pretix/static/pretixpresale/js/widget/widget.js:96
msgid "July"
msgstr "Juli"
#: pretix/static/pretixpresale/js/widget/widget.js:89
#: pretix/static/pretixpresale/js/widget/widget.js:97
msgid "August"
msgstr "August"
#: pretix/static/pretixpresale/js/widget/widget.js:90
#: pretix/static/pretixpresale/js/widget/widget.js:98
msgid "September"
msgstr "September"
#: pretix/static/pretixpresale/js/widget/widget.js:91
#: pretix/static/pretixpresale/js/widget/widget.js:99
msgid "October"
msgstr "Oktober"
#: pretix/static/pretixpresale/js/widget/widget.js:92
#: pretix/static/pretixpresale/js/widget/widget.js:100
msgid "November"
msgstr "November"
#: pretix/static/pretixpresale/js/widget/widget.js:93
#: pretix/static/pretixpresale/js/widget/widget.js:101
msgid "December"
msgstr "Dezember"

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