Compare commits

..

102 Commits

Author SHA1 Message Date
Mira Weller
ffebfce2b3 use new dialog for cart expiry notification 2025-05-16 23:49:13 +02:00
Mira Weller
62ba861cd2 use new dialog class for asynctask dialog 2025-05-16 22:50:22 +02:00
Mira Weller
c880e427c5 add dialog js 2025-05-16 22:47:41 +02:00
Mira Weller
f702d44e19 different message for expiring soon and expired carts 2025-05-16 22:38:45 +02:00
Mira Weller
2d8910e797 fix error if max_extend=None 2025-05-16 22:34:24 +02:00
Mira Weller
43a96ed3fa improve error handling 2025-05-16 22:34:16 +02:00
Mira Weller
5df9a3fa8c fix markup 2025-05-16 22:04:03 +02:00
Mira Weller
fd002e0db0 add aria references to other dialogs 2025-05-16 21:46:22 +02:00
Mira Weller
6efa9f3f55 add cart expiry notification 2025-05-16 21:44:50 +02:00
Mira Weller
dbc9a72c90 refactor asynctask, make sure waitingDialog.show() re-initializes dialog contents 2025-05-16 21:28:14 +02:00
Mira Weller
3e6373485a fix error response from CartExtend 2025-05-16 21:18:49 +02:00
Mira Weller
f26c7984dc update dialog markup 2025-05-16 21:01:55 +02:00
Mira Weller
34440dcbdd refactor dialog css 2025-05-16 20:52:29 +02:00
Mira Weller
4be74b7955 extend cart without full page reload 2025-05-16 20:47:55 +02:00
Mira Weller
587b13807d async_task: deduplicate response handling code 2025-05-16 18:36:00 +02:00
Mira Weller
4aac1df4dc remove unused imports 2025-05-15 18:03:46 +02:00
Mira Weller
ba2bd9bf54 CartManager: use safety margin timedelta for extend-while-valid to avoid race condition 2025-05-15 17:42:58 +02:00
Mira Weller
169355cd43 CartManager: use database NOW() for extend-while-valid to avoid race condition 2025-05-15 15:39:39 +02:00
Mira Weller
cf4babd400 CartManager: increment num_extended_positions only after actually extending them 2025-05-15 15:38:44 +02:00
Mira Weller
496be053ef remove CartManager(expiry) parameter 2025-05-15 14:12:58 +02:00
Mira Weller
c54be016de add max_extend to remaining tests 2025-05-15 14:11:50 +02:00
Mira Weller
245c4fc996 add test cases 2025-05-15 14:04:42 +02:00
Mira Weller
a69927da84 formatting + comments 2025-05-14 18:34:09 +02:00
Mira Weller
d07026c4f6 add extend button to user interface 2025-05-14 18:23:01 +02:00
Mira Weller
54a657c8c9 only display success message if actual extension performed 2025-05-14 18:23:01 +02:00
Mira Weller
87d9f278fb use correct aggregation 2025-05-14 18:23:01 +02:00
Mira Weller
c84d1706b4 add extend_cart_reservation task and CartExtendReservation view 2025-05-14 18:23:01 +02:00
Mira Weller
29205c490d CartManager: allow extending expiry of valid positions only up to max_extend 2025-05-14 18:23:01 +02:00
Mira Weller
b045274d8c CartPosition: add max_extend field 2025-05-14 18:23:01 +02:00
Mira Weller
9729496415 CartManager: expect reservation_time parameter instead of expiry date 2025-05-14 18:23:01 +02:00
Richard Schreiber
c17a090244 [A11y] Fix color-contrast for info/error-texts in widget (#5105) 2025-05-14 15:06:38 +02:00
Richard Schreiber
d103d8782b [A11y] fix calendar nav dropdown (#5078)
* [A11y] fix calendar nav dropdown

* update organizer calender

* keep cal-nav on one line

* simplify html

* unify calendar layouts

* fix rounding issue with .input-group select+button

* add comment to explain complex css

* fix calendar dropdown due to too broad css-selector

* reduce spacing of top-nav

* fix input-group-btn double line through rounding issue
2025-05-14 10:01:16 +02:00
Luca Sorace "Stranck
4f4903b00e Metrics: Fix Content Type header (#5099)
* Metrics: Fix Content Type header

Now it follows the PrometheusText1.0.0 ContentType header specified from their code: 32d306854b/config/config.go (L516-L529)

* Update src/pretix/base/views/metrics.py

---------

Co-authored-by: Raphael Michel <mail@raphaelmichel.de>
2025-05-13 18:42:02 +02:00
Richard Schreiber
caf291630c [A11y] add skip-link to main content (#5087)
* [A11y] add skip-link to main content

* fix contrast for skip-link

* fix overlay with back-to-organizer-link

* add fallback if no main-element

* update nav-label
2025-05-13 13:37:21 +02:00
Richard Schreiber
6d0368a1bb Fix page-header-links outline color contrast (#5096) 2025-05-13 13:36:45 +02:00
Richard Schreiber
57d33e1eb1 [A11y] fix issues with labels and tabindex in widget (#5083) 2025-05-13 13:36:11 +02:00
Raphael Michel
e6ec4cb435 Adjust headlines aside from front page (#5098) 2025-05-13 10:51:34 +02:00
Raphael Michel
6043a96575 Fix weird markup on "resend link" page (#5097) 2025-05-13 10:43:26 +02:00
Raphael Michel
5bc1fb8e81 Allow to set multiple email invoice recipients (Z#23190766) (#5090) 2025-05-13 10:31:07 +02:00
Raphael Michel
47c840b9e5 Check-in log: Correctly use name from parent product (Z#23192134) (#5091) 2025-05-13 10:10:18 +02:00
Richard Schreiber
b6007a1af4 [A11y] fix widget buy button being disabled (#5084)
* [A11y] fix widget buy button being disabled

* make dialog an alertdialog for better close-button support
2025-05-13 10:00:35 +02:00
Raphael Michel
1caa71cdbe Improve validation of Norwegian VAT IDs (#5089) 2025-05-12 17:04:58 +02:00
Richard Schreiber
1f2a0278c0 [A11y] replace b with strong for better semantics (#5086) 2025-05-12 16:43:08 +02:00
Raphael Michel
cf51c879c7 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-05-12 16:43:02 +02:00
Raphael Michel
1030e2dc1f 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-05-12 16:43:02 +02:00
Hijiri Umemoto
8d320b24a5 Translations: Update Japanese
Currently translated at 100.0% (244 of 244 strings)

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

powered by weblate
2025-05-12 16:43:02 +02:00
Hijiri Umemoto
8235132de8 Translations: Update Japanese
Currently translated at 100.0% (5869 of 5869 strings)

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

powered by weblate
2025-05-12 16:43:02 +02:00
Luca Hammer
2614f12faf 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-05-12 16:43:02 +02:00
Richard Schreiber
6f92f2324f Fix JavaScript-based required label 2025-05-12 16:35:18 +02:00
Hijiri Umemoto
aaef7579d9 Translations: Update Japanese
Currently translated at 100.0% (244 of 244 strings)

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

powered by weblate
2025-05-09 11:20:27 +02:00
Hijiri Umemoto
6b1077f881 Translations: Update Japanese
Currently translated at 100.0% (5869 of 5869 strings)

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

powered by weblate
2025-05-09 11:20:27 +02:00
조정화
6154b7fae0 Translations: Update Korean
Currently translated at 99.5% (243 of 244 strings)

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

powered by weblate
2025-05-09 11:20:27 +02:00
조정화
f43be3079f Translations: Update Korean
Currently translated at 34.1% (2003 of 5869 strings)

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

powered by weblate
2025-05-09 11:20:27 +02:00
조정화
3abe82ec77 Translations: Update Korean
Currently translated at 23.2% (1363 of 5869 strings)

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

powered by weblate
2025-05-09 11:20:27 +02:00
조정화
7b30902963 Translations: Update Korean
Currently translated at 97.1% (237 of 244 strings)

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

powered by weblate
2025-05-09 11:20:27 +02:00
조정화
a885c8d2e5 Translations: Update Korean
Currently translated at 22.2% (1303 of 5869 strings)

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

powered by weblate
2025-05-09 11:20:27 +02:00
Zona Vip
0ae98f072a 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-05-09 11:20:27 +02:00
KC Tseng
9b1a723001 Translations: Update Chinese (Traditional Han script)
Currently translated at 100.0% (244 of 244 strings)

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

powered by weblate
2025-05-09 11:20:27 +02:00
KC Tseng
46d7799cd0 Translations: Update Chinese (Traditional Han script)
Currently translated at 96.7% (5678 of 5869 strings)

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

powered by weblate
2025-05-09 11:20:27 +02:00
Raphael Michel
fcb67ec4b5 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-05-09 11:20:27 +02:00
Raphael Michel
c7565e7c8b 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-05-09 11:20:27 +02:00
Luca Martinelli [Sannita]
2316cb557a Translations: Update Italian
Currently translated at 72.5% (177 of 244 strings)

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

powered by weblate
2025-05-09 11:20:27 +02:00
Luca Martinelli [Sannita]
4de75f3ba5 Translations: Update Italian
Currently translated at 36.6% (2150 of 5869 strings)

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

powered by weblate
2025-05-09 11:20:27 +02:00
Pekka Sarkola
cb972cd6ca Translations: Update Finnish
Currently translated at 67.4% (3958 of 5869 strings)

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

powered by weblate
2025-05-09 11:20:27 +02:00
Luca Martinelli [Sannita]
3354ccf78a Translations: Update Italian
Currently translated at 36.4% (2141 of 5869 strings)

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

powered by weblate
2025-05-09 11:20:27 +02:00
Raphael Michel
f17038101c 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-05-09 11:20:27 +02:00
Raphael Michel
8e343898b4 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-05-09 11:20:27 +02:00
Foxy Hunter
09dc504c87 Translations: Update Dutch
Currently translated at 100.0% (244 of 244 strings)

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

powered by weblate
2025-05-09 11:20:27 +02:00
Foxy Hunter
d780d1d25c Translations: Update Dutch
Currently translated at 100.0% (5869 of 5869 strings)

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

powered by weblate
2025-05-09 11:20:27 +02:00
Raphael Michel
5522d67f9b API: Fix old meta values being returned when updating event (fixes #5077) (#5080) 2025-05-09 08:59:40 +02:00
Richard Schreiber
7472564c26 [A11y] Fix sneak-peek for cart (#5076) 2025-05-09 08:38:34 +02:00
Richard Schreiber
2b735bec0b [A11y] Improve customer account forms (#5034) 2025-05-09 08:36:09 +02:00
Phin Wolkwitz
3e335bcbfe Presale: Hide subevent lists if subevents exist but none are visible (Z#23186153) (#5054)
* Hide subevent lists (but not calendars) if subevents exist but none are visible, to avoid confusion during checkout
2025-05-07 13:36:50 +02:00
Richard Schreiber
f676a77536 Remove line-break before "required" in label on small screens (#5074) 2025-05-07 12:04:27 +02:00
Richard Schreiber
c487373340 [A11y] validate dates only server-side for better error message support (#5073) 2025-05-07 12:03:46 +02:00
Richard Schreiber
3e05463486 [A11y] Remove unnecessary "required" help-text in questions-step (#5075) 2025-05-06 18:20:26 +02:00
Raphael Michel
31bb0f4a91 Product list: Show icon for seated products (#5015)
* Product list: Show icon for seated products

* Use updated seat icon

* Update src/pretix/static/pretixbase/scss/_theme.scss

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

---------

Co-authored-by: Richard Schreiber <schreiber@rami.io>
2025-05-06 11:14:28 +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
116 changed files with 5319 additions and 3953 deletions

View File

@@ -87,11 +87,11 @@ dependencies = [
"pytz",
"pytz-deprecation-shim==0.1.*",
"pyuca",
"qrcode==8.1",
"qrcode==8.2",
"redis==5.2.*",
"reportlab==4.3.*",
"reportlab==4.4.*",
"requests==2.31.*",
"sentry-sdk==2.25.*",
"sentry-sdk==2.27.*",
"sepaxml==2.6.*",
"stripe==7.9.*",
"text-unidecode==1.*",
@@ -114,7 +114,7 @@ dev = [
"flake8==7.2.*",
"freezegun",
"isort==6.0.*",
"pep8-naming==0.14.*",
"pep8-naming==0.15.*",
"potypo",
"pytest-asyncio>=0.24",
"pytest-cache",

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.4.0"
__version__ = "2025.5.0.dev0"

View File

@@ -378,6 +378,8 @@ class EventSerializer(SalesChannelMigrationMixin, I18nAwareModelSerializer):
if prop.name not in meta_data:
current_object.delete()
instance._prefetched_objects_cache.clear()
# Item Meta properties
if item_meta_properties is not None:
current = list(event.item_meta_properties.all())
@@ -398,6 +400,8 @@ class EventSerializer(SalesChannelMigrationMixin, I18nAwareModelSerializer):
if prop.name not in list(item_meta_properties.keys()):
prop.delete()
instance._prefetched_objects_cache.clear()
# Seats
if seat_category_mapping is not None or ('seating_plan' in validated_data and validated_data['seating_plan'] is None):
current_mappings = {

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,

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
@@ -870,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,
@@ -888,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,

View File

@@ -0,0 +1,18 @@
# Generated by Django 4.2.20 on 2025-05-14 14:58
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('pretixbase', '0279_discount_event_date_from_discount_event_date_until'),
]
operations = [
migrations.AddField(
model_name='cartposition',
name='max_extend',
field=models.DateTimeField(null=True),
),
]

View File

@@ -3098,7 +3098,10 @@ class CartPosition(AbstractPosition):
verbose_name=_("Expiration date"),
db_index=True
)
max_extend = models.DateTimeField(
verbose_name=_("Limit for extending expiration date"),
null=True
)
tax_rate = models.DecimalField(
max_digits=7, decimal_places=2, default=Decimal('0.00'),
verbose_name=_('Tax rate')

View File

@@ -1463,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()

View File

@@ -45,6 +45,7 @@ from django.conf import settings
from django.core.exceptions import ValidationError
from django.db import DatabaseError, transaction
from django.db.models import Count, Exists, IntegerField, OuterRef, Q, Value
from django.db.models.aggregates import Min
from django.dispatch import receiver
from django.utils.timezone import make_aware, now
from django.utils.translation import (
@@ -275,7 +276,10 @@ class CartManager:
}
def __init__(self, event: Event, cart_id: str, sales_channel: SalesChannel,
invoice_address: InvoiceAddress=None, widget_data=None, expiry=None):
invoice_address: InvoiceAddress=None, widget_data=None, reservation_time: timedelta=None):
"""
Creates a new CartManager for an event.
"""
self.event = event
self.cart_id = cart_id
self.real_now_dt = now()
@@ -286,11 +290,17 @@ class CartManager:
self._subevents_cache = {}
self._variations_cache = {}
self._seated_cache = {}
self._expiry = None
self._explicit_expiry = expiry
self.invoice_address = invoice_address
self._widget_data = widget_data or {}
self._sales_channel = sales_channel
self.num_extended_positions = 0
if reservation_time:
self._reservation_time = reservation_time
else:
self._reservation_time = timedelta(minutes=self.event.settings.get('reservation_time', as_type=int))
self._expiry = self.real_now_dt + self._reservation_time
self._max_expiry_extend = self.real_now_dt + (self._reservation_time * 11)
@property
def positions(self):
@@ -305,14 +315,6 @@ class CartManager:
self._seated_cache[item, subevent] = item.seat_category_mappings.filter(subevent=subevent).exists()
return self._seated_cache[item, subevent]
def _calculate_expiry(self):
if self._explicit_expiry:
self._expiry = self._explicit_expiry
else:
self._expiry = self.real_now_dt + timedelta(
minutes=self.event.settings.get('reservation_time', as_type=int)
)
def _check_presale_dates(self):
if self.event.presale_start and time_machine_now(self.real_now_dt) < self.event.presale_start:
raise CartError(error_messages['not_started'])
@@ -329,9 +331,27 @@ class CartManager:
raise CartError(error_messages['payment_ended'])
def _extend_expiry_of_valid_existing_positions(self):
# real_now_dt is initialized at CartManager instantiation, so it's slightly in the past. Add a small
# delta to reduce risk of extending already expired CartPositions.
padded_now_dt = self.real_now_dt + timedelta(seconds=5)
# Make sure we do not extend past the max_extend timestamp, allowing users to extend their valid positions up
# to 11 times the reservation time. If we add new positions to the cart while valid positions exist, the new
# positions' reservation will also be limited to max_extend of the oldest position.
# Only after all positions expire, an ExtendOperation may reset max_extend to another 11x reservation_time.
max_extend_existing = self.positions.filter(expires__gt=padded_now_dt).aggregate(m=Min('max_extend'))['m']
if max_extend_existing:
self._expiry = min(self._expiry, max_extend_existing)
self._max_expiry_extend = max_extend_existing
# Extend this user's cart session to ensure all items in the cart expire at the same time
# We can extend the reservation of items which are not yet expired without risk
self.positions.filter(expires__gt=self.real_now_dt).update(expires=self._expiry)
if self._expiry > padded_now_dt:
self.num_extended_positions += self.positions.filter(
expires__gt=padded_now_dt, expires__lt=self._expiry,
).update(
expires=self._expiry,
)
def _delete_out_of_timeframe(self):
err = None
@@ -1246,6 +1266,7 @@ class CartManager:
item=op.item,
variation=op.variation,
expires=self._expiry,
max_extend=self._max_expiry_extend,
cart_id=self.cart_id,
voucher=op.voucher,
addon_to=op.addon_to if op.addon_to else None,
@@ -1294,7 +1315,9 @@ class CartManager:
event=self.event,
item=b.item,
variation=b.variation,
expires=self._expiry, cart_id=self.cart_id,
expires=self._expiry,
max_extend=self._max_expiry_extend,
cart_id=self.cart_id,
voucher=None,
addon_to=cp,
subevent=b.subevent,
@@ -1321,12 +1344,14 @@ class CartManager:
op.position.delete()
elif available_count == 1:
op.position.expires = self._expiry
op.position.max_extend = self._max_expiry_extend
op.position.listed_price = op.listed_price
op.position.price_after_voucher = op.price_after_voucher
# op.position.price will be updated by recompute_final_prices_and_taxes()
if op.position.pk not in deleted_positions:
try:
op.position.save(force_update=True, update_fields=['expires', 'listed_price', 'price_after_voucher'])
op.position.save(force_update=True, update_fields=['expires', 'max_extend', 'listed_price', 'price_after_voucher'])
self.num_extended_positions += 1
except DatabaseError:
# Best effort... The position might have been deleted in the meantime!
pass
@@ -1416,14 +1441,11 @@ class CartManager:
def commit(self):
self._check_presale_dates()
self._check_max_cart_size()
self._calculate_expiry()
err = self._delete_out_of_timeframe()
err = self.extend_expired_positions() or err
err = err or self._check_min_per_voucher()
self.real_now_dt = now()
self._extend_expiry_of_valid_existing_positions()
err = self._perform_operations() or err
self.recompute_final_prices_and_taxes()
@@ -1632,6 +1654,31 @@ def clear_cart(self, event: Event, cart_id: str=None, locale='en', sales_channel
raise CartError(error_messages['busy'])
@app.task(base=ProfiledEventTask, bind=True, max_retries=5, default_retry_delay=1, throws=(CartError,))
def extend_cart_reservation(self, event: Event, cart_id: str=None, locale='en', sales_channel='web', override_now_dt: datetime=None) -> dict:
"""
Resets the expiry time of a cart to the configured reservation time of this event.
Limited to 11x the reservation time.
:param event: The event ID in question
:param cart_id: The cart ID of the cart to modify
"""
with language(locale), time_machine_now_assigned(override_now_dt):
try:
sales_channel = event.organizer.sales_channels.get(identifier=sales_channel)
except SalesChannel.DoesNotExist:
raise CartError("Invalid sales channel.")
try:
try:
cm = CartManager(event=event, cart_id=cart_id, sales_channel=sales_channel)
cm.commit()
return {"success": cm.num_extended_positions, "expiry": cm._expiry, "max_expiry_extend": cm._max_expiry_extend}
except LockTimeoutException:
self.retry()
except (MaxRetriesExceededError, LockTimeoutException):
raise CartError(error_messages['busy'])
@app.task(base=ProfiledEventTask, bind=True, max_retries=5, default_retry_delay=1, throws=(CartError,))
def set_cart_addons(self, event: Event, addons: List[dict], add_to_cart_items: List[dict], cart_id: str=None, locale='en',
invoice_address: int=None, sales_channel='web', override_now_dt: datetime=None) -> None:

View File

@@ -531,7 +531,7 @@ def send_invoices_to_organizer(sender, **kwargs):
if i.event.settings.invoice_email_organizer:
with language(i.event.settings.locale):
mail(
email=i.event.settings.invoice_email_organizer,
email=[e.strip() for e in i.event.settings.invoice_email_organizer.split(",")],
subject=_('New invoice: {number}').format(number=i.number),
template=LazyI18nString.from_gettext(_(
'Hello,\n\n'

View File

@@ -2221,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,
@@ -2296,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(update_fields=['price', 'tax_rate', 'tax_value', 'tax_code'])
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:
@@ -2393,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,
@@ -2433,20 +2448,22 @@ 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 op.position in secret_dirty:
secret_dirty.remove(op.position)
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': op.position.pk,
'positionid': op.position.positionid,
'position': position.pk,
'positionid': position.positionid,
})
elif isinstance(op, self.ChangeSecretOperation):
if OrderPosition.all.filter(order__event=self.event, secret=op.new_secret).exists():
@@ -2462,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:

View File

@@ -62,6 +62,9 @@ class VATIDTemporaryError(VATIDError):
def _validate_vat_id_NO(vat_id, country_code):
# Inspired by vat_moss library
if not vat_id.startswith("NO"):
# prefix is not usually used in Norway, but expected by vat_moss library
vat_id = "NO" + vat_id
try:
vat_id = vat_moss.id.normalize(vat_id)
except ValueError:

View File

@@ -71,6 +71,7 @@ from pretix.base.reldate import (
RelativeDateField, RelativeDateTimeField, RelativeDateWrapper,
SerializerRelativeDateField, SerializerRelativeDateTimeField,
)
from pretix.base.validators import multimail_validate
from pretix.control.forms import (
ExtFileField, FontSelect, MultipleLanguagesWidget, SingleLanguageWidget,
)
@@ -1233,14 +1234,18 @@ DEFAULTS = {
'invoice_email_organizer': {
'default': '',
'type': str,
'form_class': forms.EmailField,
'serializer_class': serializers.EmailField,
'form_class': forms.CharField,
'serializer_class': serializers.CharField,
'form_kwargs': dict(
label=_("Email address to receive a copy of each invoice"),
help_text=_("Each newly created invoice will be sent to this email address shortly after creation. You can "
"use this for an automated import of invoices to your accounting system. The invoice will be "
"the only attachment of the email."),
)
validators=[multimail_validate],
),
'serializer_kwargs': dict(
validators=[multimail_validate],
),
},
'show_items_outside_presale_period': {
'default': 'True',

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="14" viewBox="0 0 18 14"
class="{{ cls }}">
<path d="M7.713 3.573c-.787-.124-1.677.472-1.511 1.529l.857 3.473c.116.579.578 1.086 1.317 1.086h3.166v3.504c0 1.108 1.556 1.113 1.556.019V8.682c0-.536-.376-1.116-1.099-1.116L9.52 7.563l-.752-2.936c-.147-.648-.583-.981-1.055-1.055v.001Z"></path>
<path d="M4.48 5.835a.6.6 0 0 0-.674.725l.71 3.441c.287 1.284 1.39 2.114 2.495 2.114h2.273c.807 0 .811-1.215-.01-1.215H7.188c-.753 0-1.375-.45-1.563-1.289l-.672-3.293c-.062-.3-.26-.452-.474-.483ZM7.433.102a1.468 1.468 0 1 0 0 2.937 1.469 1.469 0 1 0 0-2.937Z"></path>
</svg>

After

Width:  |  Height:  |  Size: 636 B

View File

@@ -80,4 +80,4 @@ def serve_metrics(request):
content = "\n".join(output) + "\n"
return HttpResponse(content)
return HttpResponse(content, content_type="text/plain;version=1.0.0;escaping=allow-utf-8")

View File

@@ -68,7 +68,7 @@ class AsyncMixin:
def get_check_url(self, task_id, ajax):
return self.request.path + '?async_id=%s' % task_id + ('&ajax=1' if ajax else '')
def _ajax_response_data(self):
def _ajax_response_data(self, value):
return {}
def _return_ajax_result(self, res, timeout=.5):
@@ -85,7 +85,7 @@ class AsyncMixin:
logger.warning('Ignored ResponseError in AsyncResult.get()')
except ConnectionError:
# Redis probably just restarted, let's just report not ready and retry next time
data = self._ajax_response_data()
data = self._ajax_response_data(None)
data.update({
'async_id': res.id,
'ready': False
@@ -93,7 +93,7 @@ class AsyncMixin:
return data
state, info = res.state, res.info
data = self._ajax_response_data()
data = self._ajax_response_data(info)
data.update({
'async_id': res.id,
'ready': ready,

View File

@@ -38,6 +38,8 @@
<script type="text/javascript" src="{% static "pretixcontrol/js/clipboard.js" %}"></script>
<script type="text/javascript" src="{% static "pretixcontrol/js/menu.js" %}"></script>
<script type="text/javascript" src="{% static "pretixcontrol/js/sb-admin-2.js" %}"></script>
<script type="text/javascript" src="{% static "pretixbase/js/dialogs.js" %}"></script>
<script type="text/javascript" src="{% static "pretixbase/js/asynctask.js" %}"></script>
<script type="text/javascript" src="{% static "pretixcontrol/js/ui/main.js" %}"></script>
<script type="text/javascript" src="{% static "pretixcontrol/js/ui/quota.js" %}"></script>
<script type="text/javascript" src="{% static "pretixcontrol/js/ui/rrule.js" %}"></script>
@@ -54,7 +56,6 @@
<script type="text/javascript" src="{% static "leaflet/leaflet.js" %}"></script>
<script type="text/javascript" src="{% static "pretixcontrol/js/ui/geo.js" %}"></script>
<script type="text/javascript" src="{% static "pretixbase/js/details.js" %}"></script>
<script type="text/javascript" src="{% static "pretixbase/js/asynctask.js" %}"></script>
<script type="text/javascript" src="{% static "sortable/Sortable.js" %}"></script>
<script type="text/javascript" src="{% static "colorpicker/bootstrap-colorpicker.js" %}"></script>
<script type="text/javascript" src="{% static "fileupload/jquery.ui.widget.js" %}"></script>
@@ -463,25 +464,7 @@
</div>
</div>
</div>
<div id="ajaxerr">
</div>
<div id="loadingmodal">
<div class="modal-card">
<div class="modal-card-icon">
<i class="fa fa-cog big-rotating-icon"></i>
</div>
<div class="modal-card-content">
<h3></h3>
<p class="text"></p>
<p class="status">{% trans "If this takes longer than a few minutes, please contact us." %}</p>
<div class="progress">
<div class="progress-bar progress-bar-success">
</div>
</div>
<div class="steps">
</div>
</div>
</div>
<div id="ajaxerr" class="modal-wrapper" hidden>
</div>
</body>
</html>

View File

@@ -85,7 +85,7 @@
<div class="checkbox">
<label>
<input type="checkbox" name="delete" value="yes" />
<b>{% trans "Permanently delete all orders created in test mode" %}</b>
<strong>{% trans "Permanently delete all orders created in test mode" %}</strong>
</label>
</div>
<div class="text-right">

View File

@@ -40,6 +40,7 @@
<th class="iconcol"></th>
<th class="iconcol"></th>
<th class="iconcol"></th>
<th class="iconcol"></th>
<th class="text-right flip">{% trans "Default price" %}</th>
<th class="action-col-2"><span class="sr-only">Edit</span></th>
</tr>
@@ -111,6 +112,14 @@
<span class="fa fa-bars fa-fw text-muted" data-toggle="tooltip" title="{% trans "Product with variations" %}"></span>
{% endif %}
</td>
<td>
{% if i.requires_seat %}
<span data-toggle="tooltip"
title="{% if request.event.has_subevents %}{% trans "Product assigned to seating plan for one or more dates" context "subevent" %}{% else %}{% trans "Product assigned to seating plan" %}{% endif %}">
{% include "icons/seat.svg" with cls="svg-icon text-muted" %}
</span>
{% endif %}
</td>
<td>
{% if i.category.is_addon %}
<span class="fa fa-plus-square fa-fw text-muted" data-toggle="tooltip"

View File

@@ -413,10 +413,7 @@
{% endif %}
{% if line.seat %}
<br />
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="14" viewBox="0 0 4.7624999 3.7041668" class="svg-icon">
<path
d="m 1.9592032,1.8522629e-4 c -0.21468,0 -0.38861,0.17394000371 -0.38861,0.38861000371 0,0.21466 0.17393,0.38861 0.38861,0.38861 0.21468,0 0.3886001,-0.17395 0.3886001,-0.38861 0,-0.21467 -0.1739201,-0.38861000371 -0.3886001,-0.38861000371 z m 0.1049,0.84543000371 c -0.20823,-0.0326 -0.44367,0.12499 -0.39998,0.40462997 l 0.20361,1.01854 c 0.0306,0.15316 0.15301,0.28732 0.3483,0.28732 h 0.8376701 v 0.92708 c 0,0.29313 0.41187,0.29447 0.41187,0.005 v -1.19115 c 0,-0.14168 -0.0995,-0.29507 -0.29094,-0.29507 l -0.65578,-10e-4 -0.1757,-0.87644 C 2.3042533,0.95300523 2.1890432,0.86500523 2.0641032,0.84547523 Z m -0.58549,0.44906997 c -0.0946,-0.0134 -0.20202,0.0625 -0.17829,0.19172 l 0.18759,0.91054 c 0.0763,0.33956 0.36802,0.55914 0.66042,0.55914 h 0.6015201 c 0.21356,0 0.21448,-0.32143 -0.003,-0.32143 H 2.1954632 c -0.19911,0 -0.36364,-0.11898 -0.41341,-0.34107 l -0.17777,-0.87126 c -0.0165,-0.0794 -0.0688,-0.11963 -0.12557,-0.12764 z"/>
</svg>
{% include "icons/seat.svg" with cls="svg-icon" %}
{{ line.seat }}
{% endif %}
{% if line.voucher %}

View File

@@ -65,7 +65,7 @@ from pretix.api.serializers.item import (
from pretix.base.forms import I18nFormSet
from pretix.base.models import (
CartPosition, Item, ItemCategory, ItemVariation, Order, Question,
QuestionAnswer, QuestionOption, Quota, Voucher,
QuestionAnswer, QuestionOption, Quota, SeatCategoryMapping, Voucher,
)
from pretix.base.models.event import SubEvent
from pretix.base.models.items import ItemAddOn, ItemBundle, ItemMetaValue
@@ -101,10 +101,16 @@ class ItemList(ListView):
template_name = 'pretixcontrol/items/index.html'
def get_queryset(self):
requires_seat = Exists(
SeatCategoryMapping.objects.filter(
product_id=OuterRef('pk'),
)
)
return Item.objects.filter(
event=self.request.event
).select_related("tax_rule").annotate(
var_count=Count('variations')
var_count=Count('variations'),
requires_seat=requires_seat,
).prefetch_related("category", "limit_sales_channels").order_by(
F('category__position').asc(nulls_first=True),
'category', 'position'

View File

@@ -42,7 +42,7 @@ 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):
@@ -408,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)
@@ -458,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)

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

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="14" viewBox="0 0 4.7624999 3.7041668">
<path
d="m 1.9592032,1.8522629e-4 c -0.21468,0 -0.38861,0.17394000371 -0.38861,0.38861000371 0,0.21466 0.17393,0.38861 0.38861,0.38861 0.21468,0 0.3886001,-0.17395 0.3886001,-0.38861 0,-0.21467 -0.1739201,-0.38861000371 -0.3886001,-0.38861000371 z m 0.1049,0.84543000371 c -0.20823,-0.0326 -0.44367,0.12499 -0.39998,0.40462997 l 0.20361,1.01854 c 0.0306,0.15316 0.15301,0.28732 0.3483,0.28732 h 0.8376701 v 0.92708 c 0,0.29313 0.41187,0.29447 0.41187,0.005 v -1.19115 c 0,-0.14168 -0.0995,-0.29507 -0.29094,-0.29507 l -0.65578,-10e-4 -0.1757,-0.87644 C 2.3042533,0.95300523 2.1890432,0.86500523 2.0641032,0.84547523 Z m -0.58549,0.44906997 c -0.0946,-0.0134 -0.20202,0.0625 -0.17829,0.19172 l 0.18759,0.91054 c 0.0763,0.33956 0.36802,0.55914 0.66042,0.55914 h 0.6015201 c 0.21356,0 0.21448,-0.32143 -0.003,-0.32143 H 2.1954632 c -0.19911,0 -0.36364,-0.11898 -0.41341,-0.34107 l -0.17777,-0.87126 c -0.0165,-0.0794 -0.0688,-0.11963 -0.12557,-0.12764 z"/>
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="14" viewBox="0 0 18 14">
<path d="M7.713 3.573c-.787-.124-1.677.472-1.511 1.529l.857 3.473c.116.579.578 1.086 1.317 1.086h3.166v3.504c0 1.108 1.556 1.113 1.556.019V8.682c0-.536-.376-1.116-1.099-1.116L9.52 7.563l-.752-2.936c-.147-.648-.583-.981-1.055-1.055v.001Z"></path>
<path d="M4.48 5.835a.6.6 0 0 0-.674.725l.71 3.441c.287 1.284 1.39 2.114 2.495 2.114h2.273c.807 0 .811-1.215-.01-1.215H7.188c-.753 0-1.375-.45-1.563-1.289l-.672-3.293c-.062-.3-.26-.452-.474-.483ZM7.433.102a1.468 1.468 0 1 0 0 2.937 1.469 1.469 0 1 0 0-2.937Z"></path>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 668 B

View File

@@ -5,7 +5,7 @@ msgstr ""
"Project-Id-Version: 1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-04-28 11:06+0000\n"
"PO-Revision-Date: 2025-04-28 11:32+0000\n"
"PO-Revision-Date: 2025-05-06 16:20+0000\n"
"Last-Translator: Raphael Michel <michel@rami.io>\n"
"Language-Team: German <https://translate.pretix.eu/projects/pretix/pretix/de/"
">\n"
@@ -14,7 +14,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.11\n"
"X-Generator: Weblate 5.11.1\n"
"X-Poedit-Bookmarks: -1,-1,904,-1,-1,-1,-1,-1,-1,-1\n"
#: pretix/_base_settings.py:87
@@ -6103,7 +6103,7 @@ msgstr "Zertifikat"
#: pretix/base/models/orders.py:3468 pretix/control/views/event.py:390
#: pretix/control/views/event.py:395
msgid "Other"
msgstr "Sonstiges"
msgstr "Sonstige"
#: pretix/base/models/organizer.py:79
msgid ""
@@ -15355,7 +15355,7 @@ msgstr ""
#: pretix/control/forms/organizer.py:195
msgid "You need to choose an event."
msgstr "Sie müssen eine Veranstaltung auswählen."
msgstr "Sie müssen eine Veranstaltung wählen."
#: pretix/control/forms/organizer.py:227
msgid "You may set only one organizer domain."
@@ -28084,7 +28084,7 @@ msgstr "Alternative Veranstalterdomain für einzelne Veranstaltungen"
#: pretix/multidomain/models.py:38
msgid "Event domain"
msgstr "Veranstaltungsdomain"
msgstr "Veranstaltungs-Domain"
#: pretix/multidomain/models.py:44
msgid "Domain name"

View File

@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-04-28 11:08+0000\n"
"PO-Revision-Date: 2025-04-28 11:32+0000\n"
"PO-Revision-Date: 2025-05-12 14:33+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.11\n"
"X-Generator: Weblate 5.11.4\n"
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
@@ -742,7 +742,7 @@ msgstr "Bitte tragen Sie eine Menge für eines der Produkte ein."
#: pretix/static/pretixpresale/js/ui/main.js:510
msgid "required"
msgstr "verpflichtend"
msgstr "erforderlich"
#: pretix/static/pretixpresale/js/ui/main.js:554
#: pretix/static/pretixpresale/js/ui/main.js:574

View File

@@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: 1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-04-28 11:06+0000\n"
"PO-Revision-Date: 2025-04-28 11:32+0000\n"
"Last-Translator: Raphael Michel <michel@rami.io>\n"
"PO-Revision-Date: 2025-05-09 22:00+0000\n"
"Last-Translator: Luca Hammer <hammer@rami.io>\n"
"Language-Team: German (informal) <https://translate.pretix.eu/projects/"
"pretix/pretix/de_Informal/>\n"
"Language: de_Informal\n"
@@ -17,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.11\n"
"X-Generator: Weblate 5.11.4\n"
#: pretix/_base_settings.py:87
msgid "English"
@@ -6099,7 +6099,7 @@ msgstr "Zertifikat"
#: pretix/base/models/orders.py:3468 pretix/control/views/event.py:390
#: pretix/control/views/event.py:395
msgid "Other"
msgstr "Sonstiges"
msgstr "Sonstige"
#: pretix/base/models/organizer.py:79
msgid ""
@@ -9464,10 +9464,10 @@ msgstr ""
"die Kurzform der Veranstaltung verwendet, gefolgt von einem Bindestrich. "
"Achtung: Wenn mehrere Veranstaltungen des selben Veranstalters den selben "
"Wert in diesem Feld nutzen, teilen sie sich den Nummernkreis, d.h. jede "
"vollständige Rechnungsnummer wird pro Veranstalter nur einmal ergeben. Diese "
"Einstellung betrifft nur zukünftige Rechnungen. Du kannst die Platzhalter %Y "
"(mit Jahrhundert) oder %y (ohne Jahrhundert) verwenden um das Jahr der "
"Rechnung einzusetzen, oder %m bzw. %d für den Tag oder Monat."
"vollständige Rechnungsnummer wird pro Veranstalter nur einmal vergeben. "
"Diese Einstellung betrifft nur zukünftige Rechnungen. Du kannst die "
"Platzhalter %Y (mit Jahrhundert) oder %y (ohne Jahrhundert) verwenden um das "
"Jahr der Rechnung einzusetzen, oder %m bzw. %d für den Tag oder Monat."
#: pretix/base/settings.py:697 pretix/base/settings.py:719
#, python-brace-format
@@ -15329,7 +15329,7 @@ msgstr ""
#: pretix/control/forms/organizer.py:195
msgid "You need to choose an event."
msgstr "Du musst eine Veranstaltung auswählen."
msgstr "Du musst eine Veranstaltung wählen."
#: pretix/control/forms/organizer.py:227
msgid "You may set only one organizer domain."
@@ -28036,7 +28036,7 @@ msgstr "Alternative Veranstalterdomain für einzelne Veranstaltungen"
#: pretix/multidomain/models.py:38
msgid "Event domain"
msgstr "Veranstaltungsdomain"
msgstr "Veranstaltungs-Domain"
#: pretix/multidomain/models.py:44
msgid "Domain name"

View File

@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-04-28 11:08+0000\n"
"PO-Revision-Date: 2025-04-28 12:21+0000\n"
"PO-Revision-Date: 2025-05-12 14:33+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.11\n"
"X-Generator: Weblate 5.11.4\n"
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
@@ -741,7 +741,7 @@ msgstr "Bitte trage eine Menge für eines der Produkte ein."
#: pretix/static/pretixpresale/js/ui/main.js:510
msgid "required"
msgstr "verpflichtend"
msgstr "erforderlich"
#: pretix/static/pretixpresale/js/ui/main.js:554
#: pretix/static/pretixpresale/js/ui/main.js:574

View File

@@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-04-28 11:06+0000\n"
"PO-Revision-Date: 2025-03-27 00:00+0000\n"
"Last-Translator: CVZ-es <damien.bremont@casadevelazquez.org>\n"
"PO-Revision-Date: 2025-05-07 06:00+0000\n"
"Last-Translator: Zona Vip <contacto@zonavip.mx>\n"
"Language-Team: Spanish <https://translate.pretix.eu/projects/pretix/pretix/"
"es/>\n"
"Language: es\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.10.4\n"
"X-Generator: Weblate 5.11.1\n"
#: pretix/_base_settings.py:87
msgid "English"
@@ -2996,11 +2996,9 @@ msgid "Repeat password"
msgstr "Repetir contraseña"
#: pretix/base/forms/questions.py:134 pretix/base/forms/questions.py:256
#, fuzzy
#| msgid "No country specified."
msgctxt "name_salutation"
msgid "not specified"
msgstr "No se especifica ningún país."
msgstr "sin especificar"
#: pretix/base/forms/questions.py:219
msgid "Please do not use special characters in names."
@@ -4270,20 +4268,14 @@ msgstr ""
"o acceder a una cuota agotada seguirá recibiendo el descuento."
#: pretix/base/models/discount.py:177
#, fuzzy
#| msgctxt "subevent"
#| msgid "All dates starting before"
msgctxt "subevent"
msgid "Available for dates starting from"
msgstr "Todas las fechas empezando antes"
msgstr "Disponible para fechas a partir de"
#: pretix/base/models/discount.py:182
#, fuzzy
#| msgctxt "subevent"
#| msgid "All dates starting before"
msgctxt "subevent"
msgid "Available for dates starting until"
msgstr "Todas las fechas empezando antes"
msgstr "Disponible para fechas hasta el"
#: pretix/base/models/discount.py:214
msgid ""
@@ -5599,19 +5591,12 @@ msgid "Unknown country code."
msgstr "Código de país desconocido."
#: pretix/base/models/items.py:1921 pretix/base/models/items.py:1923
#, fuzzy
#| msgid "The maximum count needs to be greater than the minimum count."
msgid "The maximum date must not be before the minimum value."
msgstr "El conteo máximo debe ser mayor que el conteo mínimo."
msgstr "La fecha máxima no debe ser anterior a la fecha mínima."
#: pretix/base/models/items.py:1925
#, fuzzy
#| msgid ""
#| "The maximum number of usages may not be lower than the minimum number of "
#| "usages."
msgid "The maximum value must not be lower than the minimum value."
msgstr ""
"El número máximo de usos no podrá ser inferior al número mínimo de usos."
msgstr "El valor máximo no debe ser inferior al mínimo."
#: pretix/base/models/items.py:1942
#: pretix/control/templates/pretixcontrol/items/question.html:90
@@ -6026,7 +6011,7 @@ msgstr ""
#: pretix/base/models/orders.py:2286
msgid "Service fee"
msgstr "Gastos de gestión"
msgstr "Cargo por servicio"
#: pretix/base/models/orders.py:2287
msgid "Payment fee"
@@ -11699,13 +11684,6 @@ msgid "Header image"
msgstr "Imagen de cabecera"
#: pretix/base/settings.py:2885
#, fuzzy
#| msgid ""
#| "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 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."
msgid ""
"If you provide a logo image, we will by default not show your event name and "
"date in the page header. If you use a white background, we show your logo "
@@ -11713,12 +11691,13 @@ msgid ""
"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."
msgstr ""
"Si proporciona una imagen de logotipo, de forma predeterminada no "
"mostraremos el nombre ni la fecha de su evento en el encabezado de la "
"página. De forma predeterminada, mostramos su logotipo con un tamaño de "
"hasta 1140x120 píxeles. Puede aumentar el tamaño con la configuración "
"siguiente. Recomendamos no utilizar pequeños detalles en la imagen, ya que "
"cambiará de tamaño en pantallas más pequeñas."
"Si proporciona una imagen de logotipo, por defecto no mostraremos el nombre "
"de su evento ni la fecha en la cabecera de la página. Si utiliza un fondo "
"blanco, mostraremos su logotipo con un tamaño máximo de 1140x120 píxeles. En "
"caso contrario, el tamaño máximo es de 1120x120 píxeles. Puede aumentar el "
"tamaño con la configuración que aparece a continuación. Recomendamos no "
"utilizar detalles pequeños en la imagen, ya que se redimensionará en las "
"pantallas más pequeñas."
#: pretix/base/settings.py:2906 pretix/base/settings.py:2949
msgid "Use header image in its full size"
@@ -11745,13 +11724,6 @@ msgstr ""
"título del evento."
#: pretix/base/settings.py:2929 pretix/control/forms/organizer.py:524
#, fuzzy
#| msgid ""
#| "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 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."
msgid ""
"If you provide a logo image, we will by default not show your organization "
"name in the page header. If you use a white background, we show your logo "
@@ -11759,12 +11731,13 @@ msgid ""
"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."
msgstr ""
"Si proporciona una imagen de logotipo, de forma predeterminada no "
"mostraremos el nombre de su organización en el encabezado de la página. De "
"forma predeterminada, mostramos su logotipo con un tamaño de hasta 1140x120 "
"píxeles. Puede aumentar el tamaño con la configuración siguiente. "
"Recomendamos no utilizar pequeños detalles en la imagen, ya que cambiará de "
"tamaño en pantallas más pequeñas."
"Si proporciona una imagen de logotipo, por defecto no mostraremos el nombre "
"de su organización en la cabecera de la página. Si utiliza un fondo blanco, "
"mostraremos su logotipo con un tamaño máximo de 1140x120 píxeles. En caso "
"contrario, el tamaño máximo es de 1120x120 píxeles. Puede aumentar el tamaño "
"con la configuración que aparece a continuación. Recomendamos no utilizar "
"detalles pequeños en la imagen, ya que se redimensionará en las pantallas "
"más pequeñas."
#: pretix/base/settings.py:2959
msgid "Use header image also for events without an individually uploaded logo"
@@ -17931,8 +17904,8 @@ msgid_plural ""
"Are you sure you want to permanently delete the check-ins of "
"<strong>%(count)s tickets</strong>?"
msgstr[0] ""
"¿Está seguro de que desea eliminar permanentemente los registros de "
"<strong>check-in</strong>?."
"¿Está seguro de que desea eliminar permanentemente los registros de <strong"
">check-in</strong>?"
msgstr[1] ""
"¿Estás seguro de que deseas eliminar permanentemente los registros de "
"<strong>%(count)s check-in</strong>?"
@@ -24645,32 +24618,32 @@ msgstr "Idioma preferido"
#: pretix/control/templates/pretixcontrol/pdf/index.html:200
#: pretix/control/templates/pretixcontrol/pdf/index.html:210
#, fuzzy
#| msgid "Upload custom background"
msgid "Upload PDF as background"
msgstr "Subir fondo personalizado"
msgstr "Subir PDF como fondo"
#: pretix/control/templates/pretixcontrol/pdf/index.html:202
msgid ""
"You can upload a PDF to use as a custom background. The paper size will "
"match the PDF."
msgstr ""
"Puede cargar un PDF para utilizarlo como fondo personalizado. El tamaño del "
"papel coincidirá con el PDF."
#: pretix/control/templates/pretixcontrol/pdf/index.html:217
msgid "Download current background"
msgstr "Descargar fondo actual"
#: pretix/control/templates/pretixcontrol/pdf/index.html:224
#, fuzzy
#| msgid "Date chosen by customer"
msgid "Or choose custom paper size"
msgstr "Fecha elegida por el cliente"
msgstr "O elija un tamaño de papel personalizado"
#: pretix/control/templates/pretixcontrol/pdf/index.html:226
msgid ""
"To manually change the paper size, you need to create a new, empty "
"background."
msgstr ""
"Para cambiar manualmente el tamaño del papel, debe crear un nuevo fondo "
"vacío."
#: pretix/control/templates/pretixcontrol/pdf/index.html:234
#: pretix/control/templates/pretixcontrol/pdf/index.html:321
@@ -28066,10 +28039,9 @@ msgid "until"
msgstr "hasta"
#: pretix/helpers/daterange.py:106
#, fuzzy, python-brace-format
#| msgid "{date_from} {date_to}"
#, python-brace-format
msgid "{date_from}{until}{date_to}"
msgstr "{date_from} {date_to}"
msgstr "{date_from}{until}{date_to}"
#: pretix/helpers/images.py:61 pretix/helpers/images.py:67
#: pretix/helpers/images.py:85
@@ -31857,10 +31829,8 @@ msgid "Payer name"
msgstr "Nombre del pagador"
#: pretix/plugins/stripe/templates/pretixplugins/stripe/control.html:91
#, fuzzy
#| msgid "Payment fee"
msgid "Payment receipt"
msgstr "Tarifa de pago"
msgstr "Recibo de pago"
#: pretix/plugins/stripe/templates/pretixplugins/stripe/oauth_disconnect.html:12
msgid "Do you really want to disconnect your Stripe account?"

View File

@@ -8,16 +8,16 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-04-28 11:08+0000\n"
"PO-Revision-Date: 2025-03-27 00:00+0000\n"
"PO-Revision-Date: 2025-04-29 18:00+0000\n"
"Last-Translator: CVZ-es <damien.bremont@casadevelazquez.org>\n"
"Language-Team: Spanish <https://translate.pretix.eu/projects/pretix/pretix-"
"js/es/>\n"
"Language-Team: Spanish <https://translate.pretix.eu/projects/pretix/"
"pretix-js/es/>\n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.10.4\n"
"X-Generator: Weblate 5.11.1\n"
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
@@ -918,12 +918,9 @@ msgid "Open ticket shop"
msgstr "Abrir tienda de tickets"
#: pretix/static/pretixpresale/js/widget/widget.js:48
#, fuzzy
#| msgctxt "widget"
#| msgid "Resume checkout"
msgctxt "widget"
msgid "Checkout"
msgstr "Continuar pago"
msgstr "Pasar por caja"
#: pretix/static/pretixpresale/js/widget/widget.js:49
msgctxt "widget"
@@ -1081,31 +1078,31 @@ msgstr "Dom"
#: pretix/static/pretixpresale/js/widget/widget.js:81
msgid "Monday"
msgstr ""
msgstr "Lunes"
#: pretix/static/pretixpresale/js/widget/widget.js:82
msgid "Tuesday"
msgstr ""
msgstr "Martes"
#: pretix/static/pretixpresale/js/widget/widget.js:83
msgid "Wednesday"
msgstr ""
msgstr "Miércoles"
#: pretix/static/pretixpresale/js/widget/widget.js:84
msgid "Thursday"
msgstr ""
msgstr "Jueves"
#: pretix/static/pretixpresale/js/widget/widget.js:85
msgid "Friday"
msgstr ""
msgstr "Viernes"
#: pretix/static/pretixpresale/js/widget/widget.js:86
msgid "Saturday"
msgstr ""
msgstr "Sábado"
#: pretix/static/pretixpresale/js/widget/widget.js:87
msgid "Sunday"
msgstr ""
msgstr "Domingo"
#: pretix/static/pretixpresale/js/widget/widget.js:90
msgid "January"

View File

@@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-04-28 11:06+0000\n"
"PO-Revision-Date: 2025-02-12 15:27+0000\n"
"Last-Translator: Johanna Ketola <johanna.ketola@om.org>\n"
"PO-Revision-Date: 2025-05-04 16:00+0000\n"
"Last-Translator: Pekka Sarkola <pekka.sarkola@gispo.fi>\n"
"Language-Team: Finnish <https://translate.pretix.eu/projects/pretix/pretix/"
"fi/>\n"
"Language: fi\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.1\n"
#: pretix/_base_settings.py:87
msgid "English"
@@ -57,7 +57,7 @@ msgstr "tšekki"
#: pretix/_base_settings.py:96
msgid "Croatian"
msgstr ""
msgstr "Kroatia"
#: pretix/_base_settings.py:97
msgid "Danish"
@@ -2887,7 +2887,7 @@ msgstr "Odottaa lunastusta"
#: pretix/control/templates/pretixcontrol/waitinglist/index.html:223
#: pretix/control/views/waitinglist.py:329
msgid "Voucher redeemed"
msgstr "Kuponi lunastettu"
msgstr "Kuponki lunastettu"
#: pretix/base/exporters/waitinglist.py:80
#: pretix/control/templates/pretixcontrol/waitinglist/index.html:116
@@ -4245,7 +4245,7 @@ msgstr ""
#: pretix/base/models/discount.py:177
msgctxt "subevent"
msgid "Available for dates starting from"
msgstr ""
msgstr "Saatavilla lähtien"
#: pretix/base/models/discount.py:182
#, fuzzy
@@ -9794,7 +9794,7 @@ msgstr ""
#: pretix/base/settings.py:1311
msgid "This shop represents an event"
msgstr ""
msgstr "Tämä kauppaa koskee tapahtumaa"
#: pretix/base/settings.py:1313
msgid ""
@@ -12805,15 +12805,15 @@ msgstr "Tehtävä on suoritettu."
#: pretix/control/forms/__init__.py:205
#, python-brace-format
msgid "Please do not upload files larger than {size}!"
msgstr ""
msgstr "Älä lataa tiedostoja, jotka ovat suurempia kuin {size}!"
#: pretix/control/forms/__init__.py:227
msgid "Filetype not allowed!"
msgstr ""
msgstr "Tiedostomuoto ei ole sallittu!"
#: pretix/control/forms/__init__.py:330
msgid "Community translations"
msgstr ""
msgstr "Yhteisön käännökset"
#: pretix/control/forms/__init__.py:332
#, python-brace-format
@@ -12843,7 +12843,7 @@ msgstr ""
#: pretix/control/forms/checkin.py:176
msgid "Barcode"
msgstr ""
msgstr "Viivakoodi"
#: pretix/control/forms/checkin.py:179
msgid "Check-in time"
@@ -12869,11 +12869,11 @@ msgstr "Kaikki portit"
#: pretix/control/forms/event.py:91
msgid "Use languages"
msgstr ""
msgstr "Käytä kieliä"
#: pretix/control/forms/event.py:93
msgid "Choose all languages that your event should be available in."
msgstr ""
msgstr "Valitse kaikki kielet, joita tapahtumasi käyttää."
#: pretix/control/forms/event.py:96
msgid "This is an event series"
@@ -12886,19 +12886,19 @@ msgstr ""
#: pretix/control/forms/event.py:136 pretix/control/forms/event.py:518
msgid "Event timezone"
msgstr ""
msgstr "Tapahtuman aikavyöhyke"
#: pretix/control/forms/event.py:143
msgid "I don't want to specify taxes now"
msgstr ""
msgstr "En halua määritellä veroja nyt"
#: pretix/control/forms/event.py:144
msgid "You can always configure tax rates later."
msgstr ""
msgstr "Voit aina määritellä verojen määrn myöhemmin."
#: pretix/control/forms/event.py:148
msgid "Sales tax rate"
msgstr ""
msgstr "Arvonlisävero"
#: pretix/control/forms/event.py:149
msgid ""
@@ -12927,6 +12927,8 @@ msgid ""
"Sample Conference Center\n"
"Heidelberg, Germany"
msgstr ""
"Esimerkki konferenssikeskus\n"
"Helsinki, Finland"
#: pretix/control/forms/event.py:232
msgid "Your default locale must be specified."
@@ -12956,7 +12958,7 @@ msgstr "Oletus ({value})"
#: pretix/control/forms/event.py:384 pretix/control/forms/event.py:397
msgid "Domain"
msgstr ""
msgstr "Verkkotunnus"
#: pretix/control/forms/event.py:388
msgid "You can configure this in your organizer settings."
@@ -13009,7 +13011,7 @@ msgstr ""
#: pretix/control/forms/event.py:689
msgid "Do not ask"
msgstr ""
msgstr "Älä kysy"
#: pretix/control/forms/event.py:690
msgid "Ask, but do not require input"
@@ -13393,7 +13395,7 @@ msgstr ""
#: pretix/control/forms/event.py:1723
msgid "Payment via Stripe"
msgstr ""
msgstr "Maksut Stripen kautta"
#: pretix/control/forms/event.py:1724
msgid ""
@@ -13894,7 +13896,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/checkin/checkins.html:67
#: pretix/plugins/checkinlists/exporters.py:761
msgid "Device"
msgstr ""
msgstr "Laite"
#: pretix/control/forms/filter.py:2389 pretix/control/forms/filter.py:2424
#: pretix/control/forms/filter.py:2615
@@ -14229,7 +14231,7 @@ msgstr ""
#: pretix/control/forms/item.py:447
msgid "Size"
msgstr ""
msgstr "Koko"
#: pretix/control/forms/item.py:448
msgid "Number of tickets"
@@ -14332,7 +14334,7 @@ msgstr ""
#: pretix/control/forms/item.py:1079
msgid "Add-ons"
msgstr ""
msgstr "Lisäosat"
#: pretix/control/forms/item.py:1103
msgid "You added the same add-on category twice"
@@ -14361,7 +14363,7 @@ msgstr ""
#: pretix/control/forms/item.py:1236 pretix/control/forms/orders.py:367
#: pretix/control/forms/orders.py:557
msgid "inactive"
msgstr ""
msgstr "Ei käytössä"
#: pretix/control/forms/mailsetup.py:42
msgid "Hostname"
@@ -14588,7 +14590,7 @@ msgstr ""
#: pretix/presale/templates/pretixpresale/event/checkout_membership.html:23
#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:100
msgid "Seat"
msgstr ""
msgstr "Istumapaikka"
#: pretix/control/forms/orders.py:336
#: pretix/control/templates/pretixcontrol/order/change.html:182
@@ -14609,7 +14611,7 @@ msgstr ""
#: pretix/control/forms/orders.py:552 pretix/control/forms/orders.py:570
#: pretix/control/forms/orders.py:598
msgid "(Unchanged)"
msgstr ""
msgstr "(Muuttumaton)"
#: pretix/control/forms/orders.py:469 pretix/control/forms/orders.py:593
msgid "New price (gross)"
@@ -14694,7 +14696,7 @@ msgstr "Liitä laskut"
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:20
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:30
msgid "Recipient"
msgstr ""
msgstr "Vastaanottaja"
#: pretix/control/forms/orders.py:768
#, fuzzy, python-brace-format
@@ -15032,7 +15034,7 @@ msgstr "Myyntikanava samalla tunnuksella on jo olemassa."
#: pretix/control/templates/pretixcontrol/items/question_edit.html:139
msgctxt "form"
msgid "Optional"
msgstr ""
msgstr "Valinnainen"
#: pretix/control/forms/renderers.py:148
#: pretix/control/templates/pretixcontrol/organizers/device_bulk_edit.html:26
@@ -15045,23 +15047,23 @@ msgstr "muuta"
#: pretix/control/forms/rrule.py:35
msgid "year(s)"
msgstr ""
msgstr "vuosi(a)"
#: pretix/control/forms/rrule.py:36
msgid "month(s)"
msgstr ""
msgstr "kuukausi(a)"
#: pretix/control/forms/rrule.py:37
msgid "week(s)"
msgstr ""
msgstr "viikko(ja)"
#: pretix/control/forms/rrule.py:38
msgid "day(s)"
msgstr ""
msgstr "päiviä"
#: pretix/control/forms/rrule.py:43
msgid "Interval"
msgstr ""
msgstr "Aikaväli"
#: pretix/control/forms/rrule.py:69
msgid "Number of repetitions"
@@ -15074,27 +15076,27 @@ msgstr ""
#: pretix/control/forms/rrule.py:86 pretix/control/forms/rrule.py:133
msgctxt "rrule"
msgid "first"
msgstr ""
msgstr "ensimmäinen"
#: pretix/control/forms/rrule.py:87 pretix/control/forms/rrule.py:134
msgctxt "rrule"
msgid "second"
msgstr ""
msgstr "toinen"
#: pretix/control/forms/rrule.py:88 pretix/control/forms/rrule.py:135
msgctxt "rrule"
msgid "third"
msgstr ""
msgstr "kolmas"
#: pretix/control/forms/rrule.py:89 pretix/control/forms/rrule.py:136
msgctxt "rrule"
msgid "last"
msgstr ""
msgstr "viimeinen"
#: pretix/control/forms/rrule.py:110 pretix/control/forms/rrule.py:149
#: pretix/presale/templates/pretixpresale/fragment_calendar_nav.html:21
msgid "Day"
msgstr ""
msgstr "Päivä"
#: pretix/control/forms/rrule.py:112 pretix/control/forms/rrule.py:151
msgid "Weekend day"
@@ -15140,7 +15142,7 @@ msgstr ""
#: pretix/control/forms/vouchers.py:262
msgid "Codes"
msgstr ""
msgstr "Koodit"
#: pretix/control/forms/vouchers.py:264
msgid ""
@@ -15191,11 +15193,11 @@ msgstr ""
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:42
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/send_form.html:25
msgid "Recipients"
msgstr ""
msgstr "Vastaanottajaat"
#: pretix/control/forms/vouchers.py:292
msgid "or"
msgstr ""
msgstr "tai"
#: pretix/control/forms/vouchers.py:296
msgid ""
@@ -15444,7 +15446,7 @@ msgstr ""
#: pretix/control/logdisplay.py:343 pretix/control/logdisplay.py:345
#: pretix/control/logdisplay.py:891 pretix/control/logdisplay.py:893
msgid "(unknown)"
msgstr ""
msgstr "(tuntematon)"
#: pretix/control/logdisplay.py:365
#, python-brace-format
@@ -16544,7 +16546,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/dashboard.html:3
#: pretix/control/templates/pretixcontrol/dashboard.html:5
msgid "Dashboard"
msgstr ""
msgstr "Kojelauta"
#: pretix/control/navigation.py:49 pretix/control/navigation.py:382
#: pretix/control/navigation.py:487
@@ -16559,7 +16561,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/organizers/mail.html:19
#: pretix/control/templates/pretixcontrol/organizers/property_edit.html:15
msgid "General"
msgstr ""
msgstr "Yleinen"
#: pretix/control/navigation.py:57
#: pretix/control/templates/pretixcontrol/event/quick_setup.html:151
@@ -16571,7 +16573,7 @@ msgstr ""
#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:43
#: pretix/presale/templates/pretixpresale/event/order.html:86
msgid "Payment"
msgstr ""
msgstr "Maksut"
#: pretix/control/navigation.py:73 pretix/control/views/event.py:1516
#: pretix/control/views/event.py:1518 pretix/control/views/event.py:1550
@@ -16593,17 +16595,17 @@ msgstr ""
#: pretix/control/navigation.py:97
msgid "Invoicing"
msgstr ""
msgstr "Laskutus"
#: pretix/control/navigation.py:105
msgctxt "action"
msgid "Cancellation"
msgstr ""
msgstr "Peruutus"
#: pretix/control/navigation.py:113
#: pretix/control/templates/pretixcontrol/event/widget.html:8
msgid "Widget"
msgstr ""
msgstr "Pienoisohjelma"
#: pretix/control/navigation.py:126 pretix/control/navigation.py:435
#: pretix/control/navigation.py:480
@@ -16613,11 +16615,11 @@ msgstr ""
#: pretix/plugins/returnurl/apps.py:40
#: pretix/plugins/ticketoutputpdf/apps.py:55
msgid "Settings"
msgstr ""
msgstr "Asetukset"
#: pretix/control/navigation.py:164
msgid "Categories"
msgstr ""
msgstr "Kategoriat"
#: pretix/control/navigation.py:180
msgid "Discounts"
@@ -16625,7 +16627,7 @@ msgstr "Alennukset"
#: pretix/control/navigation.py:213
msgid "Overview"
msgstr ""
msgstr "Yleiskuva"
#: pretix/control/navigation.py:221
#: pretix/control/templates/pretixcontrol/order/index.html:828
@@ -16635,11 +16637,11 @@ msgstr ""
#: pretix/plugins/reports/accountingreport.py:684
#: pretix/presale/templates/pretixpresale/event/order.html:137
msgid "Refunds"
msgstr ""
msgstr "Maksupalautukset"
#: pretix/control/navigation.py:247
msgid "Import"
msgstr ""
msgstr "Tuonti"
#: pretix/control/navigation.py:276
msgid "All vouchers"
@@ -16647,12 +16649,12 @@ msgstr ""
#: pretix/control/navigation.py:284
msgid "Tags"
msgstr ""
msgstr "Tagit"
#: pretix/control/navigation.py:296
msgctxt "navigation"
msgid "Check-in"
msgstr ""
msgstr "Ilmoittautumiset"
#: pretix/control/navigation.py:313
#: pretix/control/templates/pretixcontrol/checkin/checkins.html:4
@@ -16672,20 +16674,20 @@ msgstr "Etsi"
#: pretix/plugins/reports/accountingreport.py:677
#: pretix/plugins/reports/accountingreport.py:871
msgid "Payments"
msgstr ""
msgstr "Maksut"
#: pretix/control/navigation.py:376
msgid "User settings"
msgstr ""
msgstr "Käyttäjän asetukset"
#: pretix/control/navigation.py:387
#: pretix/control/templates/pretixcontrol/user/settings.html:16
msgid "Notifications"
msgstr ""
msgstr "Ilmoitukset"
#: pretix/control/navigation.py:392
msgid "2FA"
msgstr ""
msgstr "2FA"
#: pretix/control/navigation.py:397
msgid "Authorized apps"
@@ -16713,7 +16715,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/global_settings_base.html:5
#: pretix/control/templates/pretixcontrol/global_settings_base.html:7
msgid "Global settings"
msgstr ""
msgstr "Yleiset asetukset"
#: pretix/control/navigation.py:440
msgid "Update check"
@@ -16761,7 +16763,7 @@ msgstr "SSO palveluntarjoajat"
#: pretix/control/navigation.py:626 pretix/control/navigation.py:633
msgid "Devices"
msgstr ""
msgstr "Laitteet"
#: pretix/control/permissions.py:72 pretix/control/permissions.py:109
#: pretix/control/permissions.py:140 pretix/control/permissions.py:157
@@ -16798,13 +16800,13 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/auth/invite.html:23
#: pretix/control/templates/pretixcontrol/auth/register.html:18
msgid "Login"
msgstr ""
msgstr "Sisäänkirjautuminen"
#: pretix/control/templates/pretixcontrol/auth/invite.html:27
#: pretix/control/templates/pretixcontrol/auth/login.html:43
#: pretix/control/templates/pretixcontrol/auth/register.html:22
msgid "Register"
msgstr ""
msgstr "Rekisteröinti"
#: pretix/control/templates/pretixcontrol/auth/login.html:27
#: pretix/presale/templates/pretixpresale/fragment_login_status.html:20
@@ -16830,7 +16832,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/auth/login_2fa.html:14
msgid "Token"
msgstr ""
msgstr "Token"
#: pretix/control/templates/pretixcontrol/auth/login_2fa.html:18
#: pretix/control/templates/pretixcontrol/user/reauth.html:22
@@ -16903,7 +16905,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/auth/oauth_authorization.html:54
msgid "Error:"
msgstr ""
msgstr "Virhe:"
#: pretix/control/templates/pretixcontrol/auth/recover.html:7
msgid "Set new password"
@@ -16979,7 +16981,7 @@ msgstr ""
#: pretix/presale/templates/pretixpresale/organizers/customer_password.html:20
#: pretix/presale/templates/pretixpresale/organizers/customer_setpassword.html:20
msgid "Save"
msgstr ""
msgstr "Tallenna"
#: pretix/control/templates/pretixcontrol/auth/register.html:7
msgid "Create a new account"
@@ -17129,7 +17131,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/boxoffice/payment.html:11
msgid "ID"
msgstr ""
msgstr "ID"
#: pretix/control/templates/pretixcontrol/boxoffice/payment.html:15
msgid "ZVT Terminal"
@@ -17350,7 +17352,7 @@ msgstr[1] ""
#: pretix/presale/templates/pretixpresale/event/position_change.html:24
#: pretix/presale/templates/pretixpresale/event/position_modify.html:44
msgid "Cancel"
msgstr ""
msgstr "Peruuta"
#: pretix/control/templates/pretixcontrol/checkin/bulk_revert_confirm.html:27
#: pretix/control/templates/pretixcontrol/checkin/list_delete.html:24
@@ -17396,7 +17398,7 @@ msgstr ""
#: pretix/presale/templates/pretixpresale/organizers/customer_profile_delete.html:34
#: pretix/presale/templates/pretixpresale/organizers/customer_profiles.html:29
msgid "Delete"
msgstr ""
msgstr "Poista"
#: pretix/control/templates/pretixcontrol/checkin/checkins.html:9
#: pretix/control/templates/pretixcontrol/checkin/checkins.html:41
@@ -17445,7 +17447,7 @@ msgstr ""
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/import_form.html:91
#: pretix/presale/templates/pretixpresale/fragment_event_list_filter.html:21
msgid "Filter"
msgstr ""
msgstr "Suodatin"
#: pretix/control/templates/pretixcontrol/checkin/checkins.html:50
msgid "Your search did not match any check-ins."
@@ -17464,7 +17466,7 @@ msgstr ""
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/transaction_list.html:14
#: pretix/plugins/checkinlists/exporters.py:766
msgid "Result"
msgstr ""
msgstr "Tulos"
#: pretix/control/templates/pretixcontrol/checkin/checkins.html:78
#: pretix/control/templates/pretixcontrol/order/index.html:392
@@ -17534,11 +17536,11 @@ msgstr "Ilmoittautumis-simulaattori"
#: pretix/control/templates/pretixcontrol/orders/overview.html:20
#: pretix/plugins/ticketoutputpdf/ticketoutput.py:64
msgid "PDF"
msgstr ""
msgstr "PDF"
#: pretix/control/templates/pretixcontrol/checkin/index.html:32
msgid "CSV"
msgstr ""
msgstr "CSV"
#: pretix/control/templates/pretixcontrol/checkin/index.html:73
msgid "No attendee record was found."
@@ -17556,7 +17558,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/checkin/index.html:114
#: pretix/control/templates/pretixcontrol/user/staff_session_edit.html:29
msgid "Timestamp"
msgstr ""
msgstr "Aikaleima"
#: pretix/control/templates/pretixcontrol/checkin/index.html:125
#: pretix/control/templates/pretixcontrol/orders/index.html:165
@@ -17622,7 +17624,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/event/tax_edit.html:33
#: pretix/control/templates/pretixcontrol/items/question_edit.html:128
msgid "Advanced"
msgstr ""
msgstr "Edistynyt"
#: pretix/control/templates/pretixcontrol/checkin/list_edit.html:50
msgid ""
@@ -17669,7 +17671,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/vouchers/bulk.html:117
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/send_form.html:85
msgid "Edit"
msgstr ""
msgstr "Muokkaa"
#: pretix/control/templates/pretixcontrol/checkin/list_edit.html:89
msgid "Visualize"
@@ -17740,7 +17742,7 @@ msgstr ""
#: pretix/plugins/badges/templates/pretixplugins/badges/index.html:72
#: pretix/plugins/ticketoutputpdf/templates/pretixplugins/ticketoutputpdf/index.html:69
msgid "Clone"
msgstr ""
msgstr "Monista"
#: pretix/control/templates/pretixcontrol/checkin/simulator.html:22
msgid ""
@@ -18211,7 +18213,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/subevents/bulk.html:271
#: pretix/control/templates/pretixcontrol/subevents/bulk.html:275
msgid "Optional"
msgstr ""
msgstr "Valinnainen"
#: pretix/control/templates/pretixcontrol/event/fragment_geodata.html:22
#: pretix/control/templates/pretixcontrol/subevents/bulk_edit.html:57
@@ -18537,7 +18539,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/vouchers/bulk.html:97
#: pretix/control/templates/pretixcontrol/vouchers/bulk.html:120
msgid "Preview"
msgstr ""
msgstr "Esikatselu"
#: pretix/control/templates/pretixcontrol/event/mail.html:87
#: pretix/control/templates/pretixcontrol/organizers/mail.html:58
@@ -18615,7 +18617,7 @@ msgstr "Ota jonotuslista käyttöön"
#: pretix/control/templates/pretixcontrol/event/payment.html:66
msgid "Deadlines"
msgstr ""
msgstr "Määräpäivät"
#: pretix/control/templates/pretixcontrol/event/payment.html:74
msgctxt "unit"
@@ -18629,7 +18631,7 @@ msgstr "päivää"
#: pretix/presale/templates/pretixpresale/event/position_change_confirm.html:25
#: pretix/presale/templates/pretixpresale/event/position_giftcard.html:16
msgid "Back"
msgstr ""
msgstr "Takaisin"
#: pretix/control/templates/pretixcontrol/event/payment_provider.html:15
msgid "Payment provider:"
@@ -18637,7 +18639,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/event/payment_provider.html:21
msgid "Warning:"
msgstr ""
msgstr "Varoitus:"
#: pretix/control/templates/pretixcontrol/event/payment_provider.html:22
msgid ""
@@ -18755,7 +18757,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/event/settings_base.html:10
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:18
msgid "Congratulations!"
msgstr ""
msgstr "Onnittelut!"
#: pretix/control/templates/pretixcontrol/event/quick_setup.html:16
#: pretix/control/templates/pretixcontrol/event/settings_base.html:12
@@ -18806,7 +18808,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/event/quick_setup.html:132
#: pretix/control/views/event.py:378
msgid "Features"
msgstr ""
msgstr "Ominaisuudet"
#: pretix/control/templates/pretixcontrol/event/quick_setup.html:134
msgid ""
@@ -18848,7 +18850,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/event/settings.html:21
msgid "Basics"
msgstr ""
msgstr "Perusteet"
#: pretix/control/templates/pretixcontrol/event/settings.html:40
#: pretix/control/templates/pretixcontrol/item/create.html:144
@@ -18864,7 +18866,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/event/settings.html:59
#: pretix/control/templates/pretixcontrol/organizers/edit.html:126
msgid "Localization"
msgstr ""
msgstr "Lokalisointi"
#: pretix/control/templates/pretixcontrol/event/settings.html:66
msgid "Customer and attendee data"
@@ -18904,7 +18906,7 @@ msgstr "Muutoksia tehtyihin tilauksiin"
#: pretix/control/templates/pretixcontrol/event/settings.html:130
msgid "Texts"
msgstr ""
msgstr "Tekstit"
#: pretix/control/templates/pretixcontrol/event/settings.html:137
msgid "Confirmation text"
@@ -19826,7 +19828,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/item/include_addons.html:28
#: pretix/control/templates/pretixcontrol/item/include_addons.html:62
msgid "Add-On"
msgstr ""
msgstr "Lisäosa"
#: pretix/control/templates/pretixcontrol/item/include_addons.html:86
msgid "Add a new add-on"
@@ -19871,7 +19873,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/item/index.html:154
msgid "Availability"
msgstr ""
msgstr "Saatavuus"
#: pretix/control/templates/pretixcontrol/item/index.html:184
msgid "Tickets & Badges"
@@ -19889,7 +19891,7 @@ msgstr "Kesto"
#: pretix/control/templates/pretixcontrol/subevents/bulk.html:355
#: pretix/control/templates/pretixcontrol/subevents/bulk.html:364
msgid "minutes"
msgstr ""
msgstr "minuuttia"
#: pretix/control/templates/pretixcontrol/item/index.html:217
msgid "hours"
@@ -20013,7 +20015,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/items/discount.html:43
#: pretix/plugins/stripe/templates/pretixplugins/stripe/checkout_payment_form_card.html:53
msgid "OR"
msgstr ""
msgstr "TAI"
#: pretix/control/templates/pretixcontrol/items/discount.html:53
msgctxt "discount"
@@ -20112,7 +20114,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/items/fragment_quota_availability.html:3
msgid "Closed"
msgstr ""
msgstr "Suljettu"
#: pretix/control/templates/pretixcontrol/items/fragment_quota_availability.html:5
msgid "Sold out (pending orders)"
@@ -20125,7 +20127,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/items/fragment_quota_availability.html:11
msgid "Unlimited"
msgstr ""
msgstr "Rajoittamaton"
#: pretix/control/templates/pretixcontrol/items/fragment_quota_availability.html:14
msgid "Fully reserved"
@@ -20144,7 +20146,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/order/index.html:19
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:7
msgid "taxes"
msgstr ""
msgstr "verot"
#: pretix/control/templates/pretixcontrol/items/index.html:10
msgid ""
@@ -20551,7 +20553,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/oauth/authorized.html:18
msgid "Permissions"
msgstr ""
msgstr "Oikeudet"
#: pretix/control/templates/pretixcontrol/oauth/authorized.html:59
msgid "No applications have access to your pretix account."
@@ -20838,7 +20840,7 @@ msgstr ""
#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:40
#: pretix/presale/templates/pretixpresale/event/order_modify.html:30
msgid "(optional)"
msgstr ""
msgstr "(valinnainen)"
#: pretix/control/templates/pretixcontrol/order/delete.html:4
#: pretix/control/templates/pretixcontrol/order/delete.html:8
@@ -21115,7 +21117,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/order/index.html:690
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:444
msgid "Taxes"
msgstr ""
msgstr "Verot"
#: pretix/control/templates/pretixcontrol/order/index.html:699
#: pretix/control/templates/pretixcontrol/orders/overview.html:89
@@ -21173,7 +21175,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/order/index.html:839
#: pretix/control/templates/pretixcontrol/orders/refunds.html:60
msgid "Source"
msgstr ""
msgstr "Lähde"
#: pretix/control/templates/pretixcontrol/order/index.html:872
msgid "Cancel transfer"
@@ -21199,7 +21201,7 @@ msgstr ""
#: pretix/presale/templates/pretixpresale/event/base.html:140
#: pretix/presale/templates/pretixpresale/event/timemachine.html:30
msgid "Change"
msgstr ""
msgstr "Vaihda"
#: pretix/control/templates/pretixcontrol/order/index.html:954
#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:91
@@ -21467,7 +21469,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/order/sendmail.html:44
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/send_form.html:89
msgid "Send"
msgstr ""
msgstr "Lähetä"
#: pretix/control/templates/pretixcontrol/order/transactions.html:5
#: pretix/control/templates/pretixcontrol/order/transactions.html:8
@@ -21996,7 +21998,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/orders/overview.html:10
msgid "Sales"
msgstr ""
msgstr "Myynti"
#: pretix/control/templates/pretixcontrol/orders/overview.html:11
msgid "Revenue (gross)"
@@ -22026,7 +22028,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/orders/overview.html:80
#: pretix/plugins/reports/exporters.py:382
msgid "Purchased"
msgstr ""
msgstr "Ostettu"
#: pretix/control/templates/pretixcontrol/orders/overview.html:189
msgid ""
@@ -22604,7 +22606,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/organizers/team_members.html:67
#: pretix/control/templates/pretixcontrol/organizers/team_members.html:120
msgid "Remove"
msgstr ""
msgstr "Poista"
#: pretix/control/templates/pretixcontrol/organizers/giftcard_acceptance_list.html:66
msgid "Accept"
@@ -22911,7 +22913,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/organizers/team_members.html:21
msgid "Member"
msgstr ""
msgstr "Jäsen"
#: pretix/control/templates/pretixcontrol/organizers/team_members.html:36
msgid "Two-factor authentication enabled"
@@ -22939,7 +22941,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/organizers/team_members.html:85
#: pretix/control/templates/pretixcontrol/organizers/team_members.html:134
msgid "Add"
msgstr ""
msgstr "Lisää"
#: pretix/control/templates/pretixcontrol/organizers/team_members.html:92
msgid "API tokens"
@@ -22955,7 +22957,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/organizers/teams.html:38
msgid "Members"
msgstr ""
msgstr "Jäsenet"
#: pretix/control/templates/pretixcontrol/organizers/teams.html:54
#, python-format
@@ -23007,7 +23009,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/organizers/webhook_logs.html:73
msgid "Failed"
msgstr ""
msgstr "Epäonnistunut"
#: pretix/control/templates/pretixcontrol/organizers/webhook_logs.html:83
msgid "Request URL"
@@ -23090,7 +23092,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/pdf/index.html:31
#: pretix/plugins/banktransfer/refund_export.py:46
msgid "Code"
msgstr ""
msgstr "Koodi"
#: pretix/control/templates/pretixcontrol/pdf/index.html:35
msgid "Paste"
@@ -23158,7 +23160,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/pdf/index.html:141
#: pretix/control/templates/pretixcontrol/pdf/index.html:173
msgid "Loading…"
msgstr ""
msgstr "Lataa…"
#: pretix/control/templates/pretixcontrol/pdf/index.html:144
msgid "Start editing"
@@ -23166,12 +23168,12 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/pdf/index.html:159
msgid "Cut"
msgstr ""
msgstr "Leikkaa"
#: pretix/control/templates/pretixcontrol/pdf/index.html:163
#: pretix/control/templates/pretixcontrol/vouchers/detail.html:54
msgid "Copy"
msgstr ""
msgstr "Kopioi"
#: pretix/control/templates/pretixcontrol/pdf/index.html:180
msgid "Layout name"
@@ -23225,15 +23227,15 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/pdf/index.html:254
msgid "Style"
msgstr ""
msgstr "Tyyli"
#: pretix/control/templates/pretixcontrol/pdf/index.html:256
msgid "Dark"
msgstr ""
msgstr "Tumma"
#: pretix/control/templates/pretixcontrol/pdf/index.html:257
msgid "Light"
msgstr ""
msgstr "Vaalea"
#: pretix/control/templates/pretixcontrol/pdf/index.html:263
msgid "Image content"
@@ -23262,7 +23264,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/pdf/index.html:292
msgid "Other…"
msgstr ""
msgstr "Muu…"
#: pretix/control/templates/pretixcontrol/pdf/index.html:302
msgid "Show available placeholders"
@@ -23534,7 +23536,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/subevents/bulk.html:258
msgctxt "subevent"
msgid "Preview"
msgstr ""
msgstr "Esikatselu"
#: pretix/control/templates/pretixcontrol/subevents/bulk.html:265
msgctxt "subevent"
@@ -24040,13 +24042,13 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/user/notifications.html:72
#: pretix/control/templates/pretixcontrol/user/settings.html:20
msgid "On"
msgstr ""
msgstr "Päällä"
#: pretix/control/templates/pretixcontrol/user/notifications.html:70
#: pretix/control/templates/pretixcontrol/user/notifications.html:71
#: pretix/control/templates/pretixcontrol/user/settings.html:24
msgid "Off"
msgstr ""
msgstr "Poissa"
#: pretix/control/templates/pretixcontrol/user/notifications.html:75
msgid "You have no permission to receive this notification"
@@ -24206,7 +24208,7 @@ msgstr "Etuliite (valinnainen)"
#: pretix/control/templates/pretixcontrol/vouchers/bulk.html:21
msgctxt "number_of_things"
msgid "Number"
msgstr ""
msgstr "Numero"
#: pretix/control/templates/pretixcontrol/vouchers/bulk.html:25
msgid "Generate random codes"
@@ -25084,7 +25086,7 @@ msgstr "Kaikkia kohteita ei ole valittu."
#: pretix/control/views/item.py:471
msgid "Street"
msgstr ""
msgstr "Katu"
#: pretix/control/views/item.py:573 pretix/control/views/item.py:747
#: pretix/control/views/item.py:769
@@ -25702,7 +25704,7 @@ msgstr ""
#: pretix/control/views/organizer.py:570
msgid "Administrators"
msgstr ""
msgstr "Ylläpitäjät"
#: pretix/control/views/organizer.py:633
msgid "The team has been created. You can now add members to the team."

View File

@@ -4,8 +4,8 @@ msgstr ""
"Project-Id-Version: 1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-04-28 11:06+0000\n"
"PO-Revision-Date: 2025-04-03 20:00+0000\n"
"Last-Translator: Loïc Alejandro <loic.alejandro@e.email>\n"
"PO-Revision-Date: 2025-04-29 18:00+0000\n"
"Last-Translator: CVZ-es <damien.bremont@casadevelazquez.org>\n"
"Language-Team: French <https://translate.pretix.eu/projects/pretix/pretix/fr/"
">\n"
"Language: fr\n"
@@ -13,7 +13,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.10.4\n"
"X-Generator: Weblate 5.11.1\n"
#: pretix/_base_settings.py:87
msgid "English"
@@ -3000,11 +3000,9 @@ msgid "Repeat password"
msgstr "Répéter le mot de passe"
#: pretix/base/forms/questions.py:134 pretix/base/forms/questions.py:256
#, fuzzy
#| msgid "No country specified."
msgctxt "name_salutation"
msgid "not specified"
msgstr "Aucun pays spécifié."
msgstr "non spécifié"
#: pretix/base/forms/questions.py:219
msgid "Please do not use special characters in names."
@@ -4285,20 +4283,14 @@ msgstr ""
"quota épuisé recevront toujours la réduction."
#: pretix/base/models/discount.py:177
#, fuzzy
#| msgctxt "subevent"
#| msgid "All dates starting before"
msgctxt "subevent"
msgid "Available for dates starting from"
msgstr "Toutes les dates commençant avant"
msgstr "Disponible à partir de"
#: pretix/base/models/discount.py:182
#, fuzzy
#| msgctxt "subevent"
#| msgid "All dates starting before"
msgctxt "subevent"
msgid "Available for dates starting until"
msgstr "Toutes les dates commençant avant"
msgstr "Disponible pour des dates allant jusqu'au"
#: pretix/base/models/discount.py:214
msgid ""
@@ -5629,20 +5621,12 @@ msgid "Unknown country code."
msgstr "Code de pays inconnu."
#: pretix/base/models/items.py:1921 pretix/base/models/items.py:1923
#, fuzzy
#| msgid "The maximum count needs to be greater than the minimum count."
msgid "The maximum date must not be before the minimum value."
msgstr "Le nombre maximal doit être supérieur au nombre minimal."
msgstr "La date limite ne doit pas être antérieure à la date de début."
#: pretix/base/models/items.py:1925
#, fuzzy
#| msgid ""
#| "The maximum number of usages may not be lower than the minimum number of "
#| "usages."
msgid "The maximum value must not be lower than the minimum value."
msgstr ""
"Le nombre maximal dutilisations ne peut être inférieur au nombre minimal "
"dutilisations."
msgstr "La valeur maximale ne doit pas être inférieure à la valeur minimale."
#: pretix/base/models/items.py:1942
#: pretix/control/templates/pretixcontrol/items/question.html:90
@@ -11821,13 +11805,6 @@ msgid "Header image"
msgstr "Image den-tête"
#: pretix/base/settings.py:2885
#, fuzzy
#| msgid ""
#| "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 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."
msgid ""
"If you provide a logo image, we will by default not show your event name and "
"date in the page header. If you use a white background, we show your logo "
@@ -11835,12 +11812,13 @@ msgid ""
"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."
msgstr ""
"Si vous fournissez une image de logo, nous nafficherons pas par défaut le "
"nom et la date de votre événement dans len-tête de la page. Par défaut, "
"nous affichons votre logo avec une taille allant jusquà 1140x120 pixels. "
"Vous pouvez augmenter la taille avec le paramètre ci-dessous. Nous vous "
"recommandons de ne pas utiliser de petits détails sur limage car elle sera "
"redimensionnée sur des écrans plus petits."
"Si vous fournissez une image de logo, nous n'afficherons pas, par défaut, le "
"nom et la date de votre événement dans l'en-tête de la page. Si vous "
"utilisez un fond blanc, nous affichons votre logo dans une taille maximale "
"de 1140x120 pixels. Sinon, la taille maximale est de 1120x120 pixels. Vous "
"pouvez augmenter la taille à l'aide du paramètre ci-dessous. Nous vous "
"recommandons de ne pas utiliser de petits détails sur l'image car elle sera "
"redimensionnée sur les petits écrans."
#: pretix/base/settings.py:2906 pretix/base/settings.py:2949
msgid "Use header image in its full size"
@@ -11869,13 +11847,6 @@ msgstr ""
"le titre de lévénement sera toujours affiché."
#: pretix/base/settings.py:2929 pretix/control/forms/organizer.py:524
#, fuzzy
#| msgid ""
#| "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 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."
msgid ""
"If you provide a logo image, we will by default not show your organization "
"name in the page header. If you use a white background, we show your logo "
@@ -11883,12 +11854,13 @@ msgid ""
"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."
msgstr ""
"Si vous fournissez une image de logo, nous nafficherons pas par défaut le "
"nom de votre organisation dans len-tête de la page. Par défaut, nous "
"affichons votre logo avec une taille allant jusquà 1140x120 pixels. Vous "
"pouvez augmenter la taille avec le paramètre ci-dessous. Nous vous "
"recommandons de ne pas utiliser de petits détails sur limage car elle sera "
"redimensionnée sur des écrans plus petits."
"Si vous fournissez une image de logo, nous n'afficherons pas, par défaut, le "
"nom de votre organisation dans l'en-tête de la page. Si vous utilisez un "
"fond blanc, nous affichons votre logo dans une taille maximale de 1140x120 "
"pixels. Sinon, la taille maximale est de 1120x120 pixels. Vous pouvez "
"augmenter la taille à l'aide du paramètre ci-dessous. Nous vous recommandons "
"de ne pas utiliser de petits détails sur l'image car elle sera "
"redimensionnée sur les petits écrans."
#: pretix/base/settings.py:2959
msgid "Use header image also for events without an individually uploaded logo"
@@ -24833,32 +24805,32 @@ msgstr "Langue préférée"
#: pretix/control/templates/pretixcontrol/pdf/index.html:200
#: pretix/control/templates/pretixcontrol/pdf/index.html:210
#, fuzzy
#| msgid "Upload custom background"
msgid "Upload PDF as background"
msgstr "Télécharger un arrière-plan personnalisé"
msgstr "Télécharger un PDF comme arrière-pla"
#: pretix/control/templates/pretixcontrol/pdf/index.html:202
msgid ""
"You can upload a PDF to use as a custom background. The paper size will "
"match the PDF."
msgstr ""
"Vous pouvez télécharger un PDF à utiliser comme arrière-plan personnalisé. "
"La taille du papier correspondra à celle du PDF."
#: pretix/control/templates/pretixcontrol/pdf/index.html:217
msgid "Download current background"
msgstr "Télécharger l'arrière plan actuel"
#: pretix/control/templates/pretixcontrol/pdf/index.html:224
#, fuzzy
#| msgid "Date chosen by customer"
msgid "Or choose custom paper size"
msgstr "Date choisie par le client"
msgstr "Ou choisir un format de papier personnalisé"
#: pretix/control/templates/pretixcontrol/pdf/index.html:226
msgid ""
"To manually change the paper size, you need to create a new, empty "
"background."
msgstr ""
"Pour modifier manuellement le format du papier, vous devez créer un nouvel "
"arrière-plan vide."
#: pretix/control/templates/pretixcontrol/pdf/index.html:234
#: pretix/control/templates/pretixcontrol/pdf/index.html:321
@@ -28288,10 +28260,9 @@ msgid "until"
msgstr "jusquà"
#: pretix/helpers/daterange.py:106
#, fuzzy, python-brace-format
#| msgid "{date_from} {date_to}"
#, python-brace-format
msgid "{date_from}{until}{date_to}"
msgstr "{date_from} {date_to}"
msgstr "{date_from} {until}{date_to}"
#: pretix/helpers/images.py:61 pretix/helpers/images.py:67
#: pretix/helpers/images.py:85
@@ -32115,10 +32086,8 @@ msgid "Payer name"
msgstr "Nom du payeur"
#: pretix/plugins/stripe/templates/pretixplugins/stripe/control.html:91
#, fuzzy
#| msgid "Payment fee"
msgid "Payment receipt"
msgstr "Frais de paiement"
msgstr "Reçu de paiement"
#: pretix/plugins/stripe/templates/pretixplugins/stripe/oauth_disconnect.html:12
msgid "Do you really want to disconnect your Stripe account?"

View File

@@ -7,7 +7,7 @@ msgstr ""
"Project-Id-Version: French\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-04-28 11:08+0000\n"
"PO-Revision-Date: 2025-03-27 00:00+0000\n"
"PO-Revision-Date: 2025-04-29 18:00+0000\n"
"Last-Translator: CVZ-es <damien.bremont@casadevelazquez.org>\n"
"Language-Team: French <https://translate.pretix.eu/projects/pretix/pretix-js/"
"fr/>\n"
@@ -16,7 +16,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
"X-Generator: Weblate 5.10.4\n"
"X-Generator: Weblate 5.11.1\n"
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
@@ -918,9 +918,6 @@ msgid "Open ticket shop"
msgstr "Ouvrir la billetterie"
#: pretix/static/pretixpresale/js/widget/widget.js:48
#, fuzzy
#| msgctxt "widget"
#| msgid "Resume checkout"
msgctxt "widget"
msgid "Checkout"
msgstr "Finaliser ma commande"
@@ -1080,31 +1077,31 @@ msgstr "Di"
#: pretix/static/pretixpresale/js/widget/widget.js:81
msgid "Monday"
msgstr ""
msgstr "Lundi"
#: pretix/static/pretixpresale/js/widget/widget.js:82
msgid "Tuesday"
msgstr ""
msgstr "Mardi"
#: pretix/static/pretixpresale/js/widget/widget.js:83
msgid "Wednesday"
msgstr ""
msgstr "Mercredi"
#: pretix/static/pretixpresale/js/widget/widget.js:84
msgid "Thursday"
msgstr ""
msgstr "Jeudi"
#: pretix/static/pretixpresale/js/widget/widget.js:85
msgid "Friday"
msgstr ""
msgstr "Vendredi"
#: pretix/static/pretixpresale/js/widget/widget.js:86
msgid "Saturday"
msgstr ""
msgstr "Samedi"
#: pretix/static/pretixpresale/js/widget/widget.js:87
msgid "Sunday"
msgstr ""
msgstr "Dimanche"
#: pretix/static/pretixpresale/js/widget/widget.js:90
msgid "January"

View File

@@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-04-28 11:06+0000\n"
"PO-Revision-Date: 2025-03-19 01:00+0000\n"
"Last-Translator: Rosariocastellana <rosariocastellana@gmail.com>\n"
"PO-Revision-Date: 2025-05-05 09:40+0000\n"
"Last-Translator: \"Luca Martinelli [Sannita]\" <sannita@gmail.com>\n"
"Language-Team: Italian <https://translate.pretix.eu/projects/pretix/pretix/"
"it/>\n"
"Language: it\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.10.3\n"
"X-Generator: Weblate 5.11.1\n"
#: pretix/_base_settings.py:87
msgid "English"
@@ -2988,12 +2988,9 @@ msgid "Repeat password"
msgstr "Ripeti la password"
#: pretix/base/forms/questions.py:134 pretix/base/forms/questions.py:256
#, fuzzy
#| msgctxt "subevent"
#| msgid "No date was specified."
msgctxt "name_salutation"
msgid "not specified"
msgstr "Nessuna data è stata specificata."
msgstr "non specificato"
#: pretix/base/forms/questions.py:219
msgid "Please do not use special characters in names."
@@ -4272,14 +4269,12 @@ msgstr ""
#: pretix/base/models/discount.py:177
msgctxt "subevent"
msgid "Available for dates starting from"
msgstr ""
msgstr "Disponibile per le date a partire da"
#: pretix/base/models/discount.py:182
#, fuzzy
#| msgid "Available until"
msgctxt "subevent"
msgid "Available for dates starting until"
msgstr "Disponibile fino a"
msgstr "Disponibile per le date fino a"
#: pretix/base/models/discount.py:214
msgid ""
@@ -5592,20 +5587,12 @@ msgid "Unknown country code."
msgstr "Codice del paese sconosciuto."
#: pretix/base/models/items.py:1921 pretix/base/models/items.py:1923
#, fuzzy
#| msgid "The maximum count needs to be greater than the minimum count."
msgid "The maximum date must not be before the minimum value."
msgstr "Il conteggio massimo deve essere superiore al conteggio minimo."
msgstr "La data massima non può essere prima del valore minimo."
#: pretix/base/models/items.py:1925
#, fuzzy
#| msgid ""
#| "The maximum number of usages may not be lower than the minimum number of "
#| "usages."
msgid "The maximum value must not be lower than the minimum value."
msgstr ""
"Il numero massimo di utilizzi non può essere inferiore al numero minimo di "
"utilizzi."
msgstr "Il valore massimo non può essere inferiore al valore minimo."
#: pretix/base/models/items.py:1942
#: pretix/control/templates/pretixcontrol/items/question.html:90
@@ -9084,37 +9071,44 @@ msgstr "Permetti utilizzo di plugin con restrizioni"
#: pretix/base/settings.py:158
msgid "Allow customers to create accounts"
msgstr "Permetti ai clienti di creare account"
msgstr "Permetti ai clienti di creare un account"
#: pretix/base/settings.py:159
msgid ""
"This will allow customers to sign up for an account on your ticket shop. "
"This is a prerequisite for some advanced features like memberships."
msgstr ""
"Ciò consentirà ai clienti di registrare un account sul vostro negozio di "
"biglietti. Questo è un prerequisito per alcune funzioni avanzate come le "
"iscrizioni."
#: pretix/base/settings.py:169
msgid "Allow customers to log in with email address and password"
msgstr ""
msgstr "Permetti ai clienti di loggarsi con un indirizzo email e una password"
#: pretix/base/settings.py:170
msgid ""
"If disabled, you will need to connect one or more single-sign-on providers."
msgstr ""
"Se è disattivato, sarà necessario collegare uno o più provider single-sign-"
"on."
#: pretix/base/settings.py:180
#, fuzzy
msgid "Match orders based on email address"
msgstr "Email partecipante"
msgstr "Abbina gli ordini in base all'indirizzo e-mail"
#: pretix/base/settings.py:181
msgid ""
"This will allow registered customers to access orders made with the same "
"email address, even if the customer was not logged in during the purchase."
msgstr ""
"Ciò consentirà ai clienti registrati di accedere agli ordini effettuati con "
"lo stesso indirizzo e-mail, anche se il cliente non ha effettuato il login "
"durante l'acquisto."
#: pretix/base/settings.py:191
msgid "Activate re-usable media"
msgstr ""
msgstr "Attiva supporti riutilizzabili"
#: pretix/base/settings.py:192
msgid ""
@@ -9122,53 +9116,61 @@ msgid ""
"with physical media such as wristbands or chip cards that may be re-used for "
"different tickets or gift cards later."
msgstr ""
"La funzione di supporto riutilizzabile consente di collegare i biglietti e "
"le carte regalo con supporti fisici come braccialetti o chip card che "
"possono essere riutilizzati in seguito per altri biglietti o carte regalo."
#: pretix/base/settings.py:218
#, fuzzy
msgid "Length of barcodes"
msgstr "Codice biglietto"
msgstr "Lunghezza dei codici a barre"
#: pretix/base/settings.py:247
msgid ""
"Automatically create a new gift card if a previously unknown chip is seen"
msgstr ""
"Crea automaticamente una nuova carta regalo se viene visto un chip "
"precedentemente sconosciuto"
#: pretix/base/settings.py:260 pretix/base/settings.py:291
#, fuzzy
msgid "Gift card currency"
msgstr "Codice Gift Card"
msgstr "Valuta della carta regalo"
#: pretix/base/settings.py:278
msgid "Automatically create a new gift card if a new chip is encoded"
msgstr ""
"Crea automaticamente una nuova carta regalo se viene codificato un nuovo chip"
#: pretix/base/settings.py:300
msgid "Use UID protection feature of NFC chip"
msgstr ""
msgstr "Utilizza la funzione di protezione UID del chip NFC"
#: pretix/base/settings.py:316
msgid "Maximum number of items per order"
msgstr ""
msgstr "Numero massimo di elementi per ordine"
#: pretix/base/settings.py:317
msgid "Add-on products will not be counted."
msgstr ""
msgstr "I prodotti aggiuntivi non verranno conteggiati."
#: pretix/base/settings.py:326
msgid ""
"Show net prices instead of gross prices in the product list (not "
"recommended!)"
msgstr ""
"Mostra il prezzo netto anziché il prezzo lordo nella lista dei prodotti (non "
"raccomandato!)"
#: pretix/base/settings.py:327
msgid ""
"Independent of your choice, the cart will show gross prices as this is the "
"price that needs to be paid."
msgstr ""
"Indipendentemente dalla vostra scelta, il carrello mostrerà i prezzi lordi, "
"poiché questo è il prezzo che deve essere pagato."
#: pretix/base/settings.py:338
msgid "Hide prices on attendee ticket page"
msgstr ""
msgstr "Nascondi i prezzi nella pagina dei biglietti per i partecipanti"
#: pretix/base/settings.py:339
msgid ""
@@ -9177,10 +9179,14 @@ msgid ""
"page of the individual attendees. The ticket buyer will of course see the "
"price."
msgstr ""
"Se una persona acquista più biglietti e si inviano e-mail a tutti i "
"partecipanti, con questa opzione il prezzo del biglietto non verrà mostrato "
"nella pagina dei biglietti dei singoli partecipanti. L'acquirente del "
"biglietto vedrà ovviamente il prezzo."
#: pretix/base/settings.py:357
msgid "Ask for attendee names"
msgstr ""
msgstr "Chiedi il nome dei partecipanti"
#: pretix/base/settings.py:358
msgid "Ask for a name for all personalized tickets."
@@ -23307,10 +23313,8 @@ msgid "Download current background"
msgstr ""
#: pretix/control/templates/pretixcontrol/pdf/index.html:224
#, fuzzy
#| msgid "Canceled by customer"
msgid "Or choose custom paper size"
msgstr "Cancellato dal cliente"
msgstr "Oppure scegli un formato carta personalizzato"
#: pretix/control/templates/pretixcontrol/pdf/index.html:226
msgid ""
@@ -26399,28 +26403,18 @@ msgid "until"
msgstr "Data fino a"
#: pretix/helpers/daterange.py:106
#, fuzzy, python-brace-format
#| msgctxt "invoice"
#| msgid ""
#| "{from_date}\n"
#| "until {to_date}"
#, python-brace-format
msgid "{date_from}{until}{date_to}"
msgstr ""
"{from_date}\n"
"a {to_date}"
msgstr "{date_from}{until}{date_to}"
#: pretix/helpers/images.py:61 pretix/helpers/images.py:67
#: pretix/helpers/images.py:85
#, fuzzy
#| msgid ""
#| "The file you uploaded has a very large number of pixels, please upload an "
#| "image no larger than 10000 x 10000 pixels."
msgid ""
"The file you uploaded has a very large number of pixels, please upload a "
"picture with smaller dimensions."
msgstr ""
"Il file che hai caricato ha un numero molto elevato di pixel, per favore "
"carica un'immagine che abbia 10000 x 10000 pixel."
"carica un'immagine di dimensione più piccola."
#: pretix/helpers/security.py:166
msgid "Login from new source detected"
@@ -27013,7 +27007,7 @@ msgstr ""
#: pretix/plugins/banktransfer/payment.py:161
msgid "Do not include hyphens in the payment reference."
msgstr ""
msgstr "Non includere trattini nella referenza di pagamento."
#: pretix/plugins/banktransfer/payment.py:162
msgid "This is required in some countries."
@@ -27025,7 +27019,7 @@ msgstr ""
#: pretix/plugins/banktransfer/payment.py:170
msgid "Prefix for the payment reference"
msgstr ""
msgstr "Prefisso per il riferimento pagamento"
#: pretix/plugins/banktransfer/payment.py:174
msgid "Additional text to show on pending orders"
@@ -27249,7 +27243,7 @@ msgstr "Ti daremo il codice di riferimento dopo aver completato l'ordine."
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_payment_form.html:26
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/pending.html:39
msgid "Reference code (important):"
msgstr ""
msgstr "Codice di riferimento personale (importante):"
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_confirm.html:31
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_payment_form.html:31
@@ -27288,7 +27282,7 @@ msgstr ""
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/control.html:38
msgid "Reference code"
msgstr ""
msgstr "Codice di riferimento personale"
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/import_assign.html:4
msgid ""
@@ -30025,10 +30019,8 @@ msgid "Payer name"
msgstr ""
#: pretix/plugins/stripe/templates/pretixplugins/stripe/control.html:91
#, fuzzy
#| msgid "Payment fee"
msgid "Payment receipt"
msgstr "Commissione di pagamento"
msgstr "Ricevuta di pagamento"
#: pretix/plugins/stripe/templates/pretixplugins/stripe/oauth_disconnect.html:12
msgid "Do you really want to disconnect your Stripe account?"
@@ -30057,7 +30049,7 @@ msgstr ""
#: pretix/plugins/stripe/templates/pretixplugins/stripe/pending.html:19
msgid "Enter the entity number, reference number, and amount."
msgstr ""
msgstr "Inserire il Numero dell'entità, il codice riferimento, e la quantità."
#: pretix/plugins/stripe/templates/pretixplugins/stripe/pending.html:25
msgid "Entity number:"

View File

@@ -8,16 +8,16 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-04-28 11:08+0000\n"
"PO-Revision-Date: 2025-03-16 19:00+0000\n"
"PO-Revision-Date: 2025-05-05 09:40+0000\n"
"Last-Translator: \"Luca Martinelli [Sannita]\" <sannita@gmail.com>\n"
"Language-Team: Italian <https://translate.pretix.eu/projects/pretix/pretix-"
"js/it/>\n"
"Language-Team: Italian <https://translate.pretix.eu/projects/pretix/"
"pretix-js/it/>\n"
"Language: it\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.10.3\n"
"X-Generator: Weblate 5.11.1\n"
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
@@ -938,12 +938,9 @@ msgid "Open ticket shop"
msgstr "Apri la biglietteria"
#: pretix/static/pretixpresale/js/widget/widget.js:48
#, fuzzy
#| msgctxt "widget"
#| msgid "Resume checkout"
msgctxt "widget"
msgid "Checkout"
msgstr "Ricarica checkout"
msgstr "Checkout"
#: pretix/static/pretixpresale/js/widget/widget.js:49
msgctxt "widget"

View File

@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-04-28 11:06+0000\n"
"PO-Revision-Date: 2025-03-31 15:00+0000\n"
"PO-Revision-Date: 2025-05-12 13:00+0000\n"
"Last-Translator: Hijiri Umemoto <hijiri@umemoto.org>\n"
"Language-Team: Japanese <https://translate.pretix.eu/projects/pretix/pretix/"
"ja/>\n"
@@ -17,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Weblate 5.10.4\n"
"X-Generator: Weblate 5.11.4\n"
#: pretix/_base_settings.py:87
msgid "English"
@@ -2971,21 +2971,17 @@ msgid "Repeat password"
msgstr "パスワードを再入力してください"
#: pretix/base/forms/questions.py:134 pretix/base/forms/questions.py:256
#, fuzzy
#| msgid "No country specified."
msgctxt "name_salutation"
msgid "not specified"
msgstr "国が指定されていません"
msgstr "指定されていません"
#: pretix/base/forms/questions.py:219
msgid "Please do not use special characters in names."
msgstr ""
"Understood, I will avoid using special characters in names. Thank you for "
"the reminder."
msgstr "名前に特殊文字を使わないでください。"
#: pretix/base/forms/questions.py:281
msgid "Please enter a shorter name."
msgstr "短い名前を入力してください。"
msgstr "もっと短い名前を入力してください。"
#: pretix/base/forms/questions.py:305
msgctxt "phonenumber"
@@ -3001,11 +2997,12 @@ msgstr "電話番号(国際エリアコードなし)"
msgid ""
"You uploaded an image in landscape orientation. Please upload an image in "
"portrait orientation."
msgstr "画像を縦向きでアップロードしてください。"
msgstr "画像が横向きでアップロードされています。縦向きの画像をアップロードしてくださ"
"い。"
#: pretix/base/forms/questions.py:493
msgid "Please upload an image where the width is 3/4 of the height."
msgstr "幅が高さの3/4の画像をアップロードしてください。"
msgstr "縦4x幅3の比率の画像をアップロードしてください。"
#: pretix/base/forms/questions.py:496
msgid ""
@@ -3059,7 +3056,7 @@ msgstr "会社名を提供する必要があります。"
#: pretix/base/forms/questions.py:1187
msgid "You need to provide your name."
msgstr "私はアシスタントです。"
msgstr "あなたの名前を提供する必要があります。"
#: pretix/base/forms/user.py:51 pretix/control/forms/users.py:43
msgid ""
@@ -3631,12 +3628,12 @@ msgstr "有効な販売チャネルを入力してください。"
#: pretix/base/modelimport_orders.py:585
#: pretix/base/modelimport_vouchers.py:291
msgid "Multiple matching seats were found."
msgstr "複数のマッチングする席が見つかりました。"
msgstr "該当する席が複数見つかりました。"
#: pretix/base/modelimport_orders.py:587
#: pretix/base/modelimport_vouchers.py:293
msgid "No matching seat was found."
msgstr "適合する席が見つかりませんでした。"
msgstr "該当する席が見つかりませんでした。"
#: pretix/base/modelimport_orders.py:590
#: pretix/base/modelimport_vouchers.py:296 pretix/base/services/cart.py:212
@@ -3674,7 +3671,7 @@ msgstr "顧客"
#: pretix/base/modelimport_orders.py:711
msgid "No matching customer was found."
msgstr "顧客が見つかりませんでした。"
msgstr "該当する顧客が見つかりませんでした。"
#: pretix/base/modelimport_vouchers.py:50 pretix/base/models/vouchers.py:488
msgid "A voucher with this code already exists."
@@ -3815,7 +3812,7 @@ msgstr "電源を切ると、通知を受け取れません。"
#: pretix/control/templates/pretixcontrol/users/form.html:6
#: pretix/control/views/organizer.py:158 tests/base/test_mail.py:149
msgid "User"
msgstr "ユーザ"
msgstr "ユーザ"
#: pretix/base/models/auth.py:284 pretix/control/navigation.py:411
#: pretix/control/templates/pretixcontrol/users/index.html:5
@@ -4234,20 +4231,14 @@ msgstr ""
"れます。"
#: pretix/base/models/discount.py:177
#, fuzzy
#| msgctxt "subevent"
#| msgid "All dates starting before"
msgctxt "subevent"
msgid "Available for dates starting from"
msgstr "すべての日付は、前に始まります"
msgstr "この日から始まる日付で利用可能"
#: pretix/base/models/discount.py:182
#, fuzzy
#| msgctxt "subevent"
#| msgid "All dates starting before"
msgctxt "subevent"
msgid "Available for dates starting until"
msgstr "すべての日付は、前に始まります"
msgstr "これより以前に開始する日付で利用可能"
#: pretix/base/models/discount.py:214
msgid ""
@@ -5513,18 +5504,12 @@ msgid "Unknown country code."
msgstr "不明な国コード。"
#: pretix/base/models/items.py:1921 pretix/base/models/items.py:1923
#, fuzzy
#| msgid "The maximum count needs to be greater than the minimum count."
msgid "The maximum date must not be before the minimum value."
msgstr "最大数は最小よりも大きくする必要があります。"
msgstr "最大日付は、最小より前でなければなりません。"
#: pretix/base/models/items.py:1925
#, fuzzy
#| msgid ""
#| "The maximum number of usages may not be lower than the minimum number of "
#| "usages."
msgid "The maximum value must not be lower than the minimum value."
msgstr "使用回数の最大値は最小回数より低くすることはできません。"
msgstr "最大値は最小より低くできません。"
#: pretix/base/models/items.py:1942
#: pretix/control/templates/pretixcontrol/items/question.html:90
@@ -11383,13 +11368,6 @@ msgid "Header image"
msgstr "ヘッダー画像"
#: pretix/base/settings.py:2885
#, fuzzy
#| msgid ""
#| "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 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."
msgid ""
"If you provide a logo image, we will by default not show your event name and "
"date in the page header. If you use a white background, we show your logo "
@@ -11397,11 +11375,11 @@ msgid ""
"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."
msgstr ""
"ロゴ画像を提供していただければ、デフォルトではイベント名と日付はページヘッ"
"ダーに表示されません。デフォルトでは、1140x120ピクセルまでのサイズでロゴが表"
"示されます。以下の設定でサイズを拡大することもできます。画像に細かいディテー"
"ルを使用しないことをお勧めします。なぜなら、小さな画面ではサイズされるため"
"す。"
"ロゴ画像を提供すると、デフォルトでページヘッダーにイベント名と日付が表示され"
"ません。白い背景を使用する場合、最大1140x120ピクセルのサイズでロゴが表示され"
"ます。それ以外の場合、最大サイズは1120x120ピクセルです。以下の設定でサイズを"
"大きくすることができます。小さな画面ではサイズが変更されるため、写真に小さな"
"ディテールを使用しないことをお勧めします。"
#: pretix/base/settings.py:2906 pretix/base/settings.py:2949
msgid "Use header image in its full size"
@@ -11427,13 +11405,6 @@ msgstr ""
"れます。"
#: pretix/base/settings.py:2929 pretix/control/forms/organizer.py:524
#, fuzzy
#| msgid ""
#| "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 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."
msgid ""
"If you provide a logo image, we will by default not show your organization "
"name in the page header. If you use a white background, we show your logo "
@@ -19792,7 +19763,7 @@ msgstr "クォータごとの有料チケット"
#: pretix/control/views/dashboards.py:519 pretix/control/views/typeahead.py:89
msgctxt "subevent"
msgid "No dates"
msgstr "データなし"
msgstr "日付なし"
#: pretix/control/templates/pretixcontrol/events/index.html:141
#: pretix/control/templates/pretixcontrol/subevents/index.html:158
@@ -23989,32 +23960,29 @@ msgstr "優先する言語"
#: pretix/control/templates/pretixcontrol/pdf/index.html:200
#: pretix/control/templates/pretixcontrol/pdf/index.html:210
#, fuzzy
#| msgid "Upload custom background"
msgid "Upload PDF as background"
msgstr "カスタム背景をアップロード"
msgstr "背景としてPDFをアップロードする"
#: pretix/control/templates/pretixcontrol/pdf/index.html:202
msgid ""
"You can upload a PDF to use as a custom background. The paper size will "
"match the PDF."
msgstr ""
msgstr "PDF をアップロードして、カスタムの背景として使用できます。用紙のサイズは PDF "
"と一致します。"
#: pretix/control/templates/pretixcontrol/pdf/index.html:217
msgid "Download current background"
msgstr "現在の背景をダウンロード"
#: pretix/control/templates/pretixcontrol/pdf/index.html:224
#, fuzzy
#| msgid "Date chosen by customer"
msgid "Or choose custom paper size"
msgstr "お客様が選んだ日付"
msgstr "または、カスタム用紙サイズを選択"
#: pretix/control/templates/pretixcontrol/pdf/index.html:226
msgid ""
"To manually change the paper size, you need to create a new, empty "
"background."
msgstr ""
msgstr "用紙サイズを手動で変更するには、新しい空の背景を作成する必要があります。"
#: pretix/control/templates/pretixcontrol/pdf/index.html:234
#: pretix/control/templates/pretixcontrol/pdf/index.html:321
@@ -27322,10 +27290,9 @@ msgid "until"
msgstr "まで"
#: pretix/helpers/daterange.py:106
#, fuzzy, python-brace-format
#| msgid "{date_from} {date_to}"
#, python-brace-format
msgid "{date_from}{until}{date_to}"
msgstr "{date_from} {date_to}"
msgstr "{date_from}{until}{date_to}"
#: pretix/helpers/images.py:61 pretix/helpers/images.py:67
#: pretix/helpers/images.py:85
@@ -31012,10 +30979,8 @@ msgid "Payer name"
msgstr "支払い者の名前"
#: pretix/plugins/stripe/templates/pretixplugins/stripe/control.html:91
#, fuzzy
#| msgid "Payment fee"
msgid "Payment receipt"
msgstr "支払手数料"
msgstr "領収書"
#: pretix/plugins/stripe/templates/pretixplugins/stripe/oauth_disconnect.html:12
msgid "Do you really want to disconnect your Stripe account?"

View File

@@ -8,16 +8,16 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-04-28 11:08+0000\n"
"PO-Revision-Date: 2025-03-31 15:00+0000\n"
"PO-Revision-Date: 2025-05-12 13:00+0000\n"
"Last-Translator: Hijiri Umemoto <hijiri@umemoto.org>\n"
"Language-Team: Japanese <https://translate.pretix.eu/projects/pretix/pretix-"
"js/ja/>\n"
"Language-Team: Japanese <https://translate.pretix.eu/projects/pretix/"
"pretix-js/ja/>\n"
"Language: ja\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Weblate 5.10.4\n"
"X-Generator: Weblate 5.11.4\n"
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
@@ -233,7 +233,7 @@ msgstr "未払い"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:44
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:45
msgid "Canceled"
msgstr "キャンセル"
msgstr "キャンセル済み"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:46
msgid "Confirmed"
@@ -907,12 +907,9 @@ msgid "Open ticket shop"
msgstr "チケットショップを開く"
#: pretix/static/pretixpresale/js/widget/widget.js:48
#, fuzzy
#| msgctxt "widget"
#| msgid "Resume checkout"
msgctxt "widget"
msgid "Checkout"
msgstr "購入を続行する"
msgstr "チェックアウト"
#: pretix/static/pretixpresale/js/widget/widget.js:49
msgctxt "widget"
@@ -1068,31 +1065,31 @@ msgstr "日"
#: pretix/static/pretixpresale/js/widget/widget.js:81
msgid "Monday"
msgstr ""
msgstr "月曜日"
#: pretix/static/pretixpresale/js/widget/widget.js:82
msgid "Tuesday"
msgstr ""
msgstr "火曜日"
#: pretix/static/pretixpresale/js/widget/widget.js:83
msgid "Wednesday"
msgstr ""
msgstr "水曜日"
#: pretix/static/pretixpresale/js/widget/widget.js:84
msgid "Thursday"
msgstr ""
msgstr "木曜日"
#: pretix/static/pretixpresale/js/widget/widget.js:85
msgid "Friday"
msgstr ""
msgstr "金曜日"
#: pretix/static/pretixpresale/js/widget/widget.js:86
msgid "Saturday"
msgstr ""
msgstr "土曜日"
#: pretix/static/pretixpresale/js/widget/widget.js:87
msgid "Sunday"
msgstr ""
msgstr "日曜日"
#: pretix/static/pretixpresale/js/widget/widget.js:90
msgid "January"

File diff suppressed because it is too large Load Diff

View File

@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-04-28 11:08+0000\n"
"PO-Revision-Date: 2025-04-16 10:00+0000\n"
"PO-Revision-Date: 2025-05-08 10:00+0000\n"
"Last-Translator: 조정화 <junghwa.jo@om.org>\n"
"Language-Team: Korean <https://translate.pretix.eu/projects/pretix/pretix-js/"
"ko/>\n"
@@ -17,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Weblate 5.10.4\n"
"X-Generator: Weblate 5.11.4\n"
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
@@ -1084,31 +1084,31 @@ msgstr "일요일"
#: pretix/static/pretixpresale/js/widget/widget.js:81
msgid "Monday"
msgstr ""
msgstr "월요일"
#: pretix/static/pretixpresale/js/widget/widget.js:82
msgid "Tuesday"
msgstr ""
msgstr "화요일"
#: pretix/static/pretixpresale/js/widget/widget.js:83
msgid "Wednesday"
msgstr ""
msgstr "수요일"
#: pretix/static/pretixpresale/js/widget/widget.js:84
msgid "Thursday"
msgstr ""
msgstr "목요일"
#: pretix/static/pretixpresale/js/widget/widget.js:85
msgid "Friday"
msgstr ""
msgstr "금요일"
#: pretix/static/pretixpresale/js/widget/widget.js:86
msgid "Saturday"
msgstr ""
msgstr "토요일"
#: pretix/static/pretixpresale/js/widget/widget.js:87
msgid "Sunday"
msgstr ""
msgstr "일요일"
#: pretix/static/pretixpresale/js/widget/widget.js:90
msgid "January"

View File

@@ -7,16 +7,16 @@ msgstr ""
"Project-Id-Version: 1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-04-28 11:06+0000\n"
"PO-Revision-Date: 2025-03-30 16:00+0000\n"
"Last-Translator: Jan Van Haver <jan.van.haver@gmail.com>\n"
"Language-Team: Dutch <https://translate.pretix.eu/projects/pretix/pretix/nl/"
">\n"
"PO-Revision-Date: 2025-05-01 02:00+0000\n"
"Last-Translator: Foxy Hunter <matthias.vancoillie@outlook.com>\n"
"Language-Team: Dutch <https://translate.pretix.eu/projects/pretix/pretix/nl/>"
"\n"
"Language: nl\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.10.4\n"
"X-Generator: Weblate 5.11.1\n"
#: pretix/_base_settings.py:87
msgid "English"
@@ -2980,11 +2980,9 @@ msgid "Repeat password"
msgstr "Herhaal wachtwoord"
#: pretix/base/forms/questions.py:134 pretix/base/forms/questions.py:256
#, fuzzy
#| msgid "No country specified."
msgctxt "name_salutation"
msgid "not specified"
msgstr "Geen land opgegeven."
msgstr "Niet opgegeven"
#: pretix/base/forms/questions.py:219
msgid "Please do not use special characters in names."
@@ -3999,7 +3997,7 @@ msgstr "Bestelling niet goedgekeurd"
#: pretix/base/models/checkin.py:366
msgid "Ticket not valid at this time"
msgstr "Ticket is niet geldig op dit moment"
msgstr "Ticket is op dit moment niet geldig"
#: pretix/base/models/customers.py:55
msgid "Provider name"
@@ -4253,20 +4251,14 @@ msgstr ""
"uitverkochte producten zullen nog steeds een korting krijgen."
#: pretix/base/models/discount.py:177
#, fuzzy
#| msgctxt "subevent"
#| msgid "All dates starting before"
msgctxt "subevent"
msgid "Available for dates starting from"
msgstr "Alle subevenementen beginnend voor"
msgstr "Beschikbaar vanaf de volgende datums"
#: pretix/base/models/discount.py:182
#, fuzzy
#| msgctxt "subevent"
#| msgid "All dates starting before"
msgctxt "subevent"
msgid "Available for dates starting until"
msgstr "Alle subevenementen beginnend voor"
msgstr "Beschikbaar voor startdatums tot"
#: pretix/base/models/discount.py:214
msgid ""
@@ -5576,20 +5568,12 @@ msgid "Unknown country code."
msgstr "Onbekende landcode."
#: pretix/base/models/items.py:1921 pretix/base/models/items.py:1923
#, fuzzy
#| msgid "The maximum count needs to be greater than the minimum count."
msgid "The maximum date must not be before the minimum value."
msgstr "Het maximale aantal moet groter zijn dan het minimum aantal."
msgstr "De maximumdatum mag niet vóór de minimumwaarde liggen."
#: pretix/base/models/items.py:1925
#, fuzzy
#| msgid ""
#| "The maximum number of usages may not be lower than the minimum number of "
#| "usages."
msgid "The maximum value must not be lower than the minimum value."
msgstr ""
"Het maximum aantal keer gebruikt mag niet lager zijn dan het minimum aantal "
"keer gebruikt."
msgstr "De maximum waarde mag niet lager zijn dan de minimum waarde."
#: pretix/base/models/items.py:1942
#: pretix/control/templates/pretixcontrol/items/question.html:90
@@ -6298,8 +6282,6 @@ msgstr ""
"Gemiddeld tarief (andere omzet in een agriculturele en bosbouwkundig bedrijf)"
#: pretix/base/models/tax.py:164
#, fuzzy
#| msgid "Reverse charge"
msgctxt "tax_code"
msgid "Reverse charge"
msgstr "Omgekeerde belastingheffing"
@@ -6347,7 +6329,7 @@ msgstr "Canarische Eilanden algemeen belastingtarief"
#: pretix/base/models/tax.py:190
msgctxt "tax_code"
msgid "Tax for production, services and importation in Ceuta and Melilla"
msgstr ""
msgstr "Belasting op productie, diensten en invoer in Ceuta en Melilla"
#: pretix/base/models/tax.py:191
msgctxt "tax_code"
@@ -6416,14 +6398,14 @@ msgstr "Intracommunautaire aankoop van verzamelobjecten en antiek"
#: pretix/base/models/tax.py:262
msgctxt "tax_code"
msgid "France domestic VAT franchise in base"
msgstr ""
msgstr "Franse btw-vrijstelling (binnenlands, franchise)"
#: pretix/base/models/tax.py:264
msgctxt "tax_code"
msgid ""
"France domestic Credit Notes without VAT, due to supplier forfeit of VAT for "
"discount"
msgstr ""
msgstr "Franse binnenlandse creditnota, geen betw door korting van leverancier"
#: pretix/base/models/tax.py:314
msgid "Your set of rules is not valid. Error message: {}"
@@ -6447,6 +6429,9 @@ msgid ""
"If you help us understand what this tax rules legally is, we can use this "
"information for eInvoices, exporting to accounting system, etc."
msgstr ""
"Wanneer je ons helpt te begrijpen wat deze belastingsregels juridisch "
"inhouden, kunnen we deze informatie inzetten voor e-facturen, het exporteren "
"naar het boekhoudsysteem, enz."
#: pretix/base/models/tax.py:351
msgid "The configured product prices include the tax amount"
@@ -6516,11 +6501,15 @@ msgstr "U moet uw thuisland instellen om de verleggingsfunctie te gebruiken."
msgid ""
"A combination of this tax code with a non-zero tax rate does not make sense."
msgstr ""
"Een combinatie van deze belastingcode met een belastingtarief groter dan nul "
"is niet logisch."
#: pretix/base/models/tax.py:421 pretix/control/forms/event.py:1562
msgid ""
"A combination of this tax code with a zero tax rate does not make sense."
msgstr ""
"Een combinatie van deze belastingscode met een belastingstarief van nul is "
"niet logisch."
#: pretix/base/models/tax.py:426
#, python-brace-format
@@ -11660,13 +11649,6 @@ msgid "Header image"
msgstr "Header-afbeelding"
#: pretix/base/settings.py:2885
#, fuzzy
#| msgid ""
#| "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 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."
msgid ""
"If you provide a logo image, we will by default not show your event name and "
"date in the page header. If you use a white background, we show your logo "
@@ -11705,13 +11687,6 @@ msgstr ""
"organisator dan zal de titel altijd getoond worden."
#: pretix/base/settings.py:2929 pretix/control/forms/organizer.py:524
#, fuzzy
#| msgid ""
#| "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 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."
msgid ""
"If you provide a logo image, we will by default not show your organization "
"name in the page header. If you use a white background, we show your logo "
@@ -11721,7 +11696,7 @@ msgid ""
msgstr ""
"Als u een logo opgeeft zullen we standaard niet uw organisatienaam in de "
"paginaheader tonen. We tonen uw logo standaard met een maximumgrootte van "
"1140x120 pixels. U kunt deze grootte aanpassen met de instelling hieronder. "
"1120x120 pixels. U kunt deze grootte aanpassen met de instelling hieronder. "
"We raden aan om geen kleine details op de afbeelding te gebruiken, omdat de "
"afbeelding op kleinere schermen zal worden geschaald."
@@ -13570,6 +13545,8 @@ msgid ""
"A combination of this calculation mode with a non-zero tax rate does not "
"make sense."
msgstr ""
"Een combinatie van deze berekeningsmodus met een belastingstarief groter dan "
"nul is niet logisch."
#: pretix/control/forms/event.py:1550 pretix/control/forms/event.py:1554
msgid "This combination of calculation mode and tax code does not make sense."
@@ -13786,7 +13763,7 @@ msgstr "Goedgekeurd, wacht op betaling"
#: pretix/plugins/reports/exporters.py:380
#: pretix/presale/templates/pretixpresale/event/fragment_order_status.html:7
msgid "Approval pending"
msgstr "Wachtend op goedkeuring"
msgstr "Goedkeuring in afwachting"
#: pretix/control/forms/filter.py:241
msgid "Follow-up configured"
@@ -15008,6 +14985,8 @@ msgid ""
"This affects both the ticket secret (often used as a QR code) as well as the "
"link used to individually access the ticket."
msgstr ""
"Dit heeft invloed op zowel het ticketgeheim (vaak gebruikt als QR-code) als "
"de link waarmee het ticket individueel kan worden geopend."
#: pretix/control/forms/orders.py:501
msgid "Cancel this position"
@@ -15434,6 +15413,8 @@ msgid ""
"Optional query parameters, that will be added to calls to the authorization "
"endpoint. Enter as: {example}"
msgstr ""
"Optionele queryparameters, die worden toegevoegd aan oproepen naar het "
"autorisatie-eindpunt. Voer in als: {example}"
#: pretix/control/forms/organizer.py:1110
msgid "Invalidate old client secret and generate a new one"
@@ -23679,9 +23660,9 @@ msgid ""
"before you are allowed to use cookies or similar technology for analytics, "
"tracking, payment, or similar purposes."
msgstr ""
"In sommige rechtsgebieden, waaronder de Europese Unie, is toestemming van de "
"gebruiker vereist voordat u cookies of vergelijkbare technologie mag "
"gebruiken voor analyses, tracking, betaling of soortgelijke doeleinden."
"Bepaalde rechtsgebieden, zoals de Europese Unie, vereisen de toestemming van "
"de gebruiker voordat je cookies of soortgelijke technologieën mag gebruiken "
"voor analyses, tracking, betalingen of soortgelijke doeleinden."
#: pretix/control/templates/pretixcontrol/organizers/edit.html:172
msgid ""
@@ -23713,12 +23694,12 @@ msgid ""
"usage, the legal details in your specific jurisdiction, or the agreements "
"you have with third parties such as payment or tracking providers."
msgstr ""
"Niettemin blijft het uw verantwoordelijkheid om ervoor te zorgen dat uw "
"ticketshop aan alle toepasselijke wetten voldoet. Wij proberen u te helpen "
"met deze instellingen, maar kunnen geen aansprakelijkheid aanvaarden omdat "
"wij onder andere niet de exacte configuratie van uw ticketshop, de "
"juridische details van het toepasselijke rechtsgebied en de overeenkomsten "
"tussen u en de gebruikte derde aanbieders kennen."
"Het is uiteindelijk uw verantwoordelijkheid om ervoor te zorgen dat u "
"voldoet aan alle relevante wetgeving. Wij bieden deze instellingen ter "
"ondersteuning, maar kunnen geen aansprakelijkheid dragen, aangezien wij de "
"exacte configuratie van uw gebruik van pretix, de juridische details in uw "
"rechtsgebied, of de afspraken met derden zoals betalings- of "
"trackingaanbieders niet kennen."
#: pretix/control/templates/pretixcontrol/organizers/edit.html:210
msgid "Barcode media"
@@ -24553,32 +24534,32 @@ msgstr "Voorkeurstaal"
#: pretix/control/templates/pretixcontrol/pdf/index.html:200
#: pretix/control/templates/pretixcontrol/pdf/index.html:210
#, fuzzy
#| msgid "Upload custom background"
msgid "Upload PDF as background"
msgstr "Upload aangepaste achtergrond"
msgstr "Upload PDF als achtergrond"
#: pretix/control/templates/pretixcontrol/pdf/index.html:202
msgid ""
"You can upload a PDF to use as a custom background. The paper size will "
"match the PDF."
msgstr ""
"Je kunt een PDF uploaden om als aangepaste achtergrond te gebruiken. De "
"papier-grootte zal overeenkomen met dat van de PDF."
#: pretix/control/templates/pretixcontrol/pdf/index.html:217
msgid "Download current background"
msgstr "Download huidige achtergrond"
#: pretix/control/templates/pretixcontrol/pdf/index.html:224
#, fuzzy
#| msgid "Date chosen by customer"
msgid "Or choose custom paper size"
msgstr "Datum gekozen door klant"
msgstr "Of kies een aangepaste papier-grootte"
#: pretix/control/templates/pretixcontrol/pdf/index.html:226
msgid ""
"To manually change the paper size, you need to create a new, empty "
"background."
msgstr ""
"Om manueel de papier-grootte te kunnen aanpassen, moet je eerst een nieuwe, "
"lege, achtergrond maken."
#: pretix/control/templates/pretixcontrol/pdf/index.html:234
#: pretix/control/templates/pretixcontrol/pdf/index.html:321
@@ -27962,10 +27943,9 @@ msgid "until"
msgstr "tot"
#: pretix/helpers/daterange.py:106
#, fuzzy, python-brace-format
#| msgid "{date_from} {date_to}"
#, python-brace-format
msgid "{date_from}{until}{date_to}"
msgstr "{date_from} {date_to}"
msgstr "{date_from}{until}{date_to}"
#: pretix/helpers/images.py:61 pretix/helpers/images.py:67
#: pretix/helpers/images.py:85
@@ -31726,10 +31706,8 @@ msgid "Payer name"
msgstr "Naam betaler"
#: pretix/plugins/stripe/templates/pretixplugins/stripe/control.html:91
#, fuzzy
#| msgid "Payment fee"
msgid "Payment receipt"
msgstr "Betalingskosten"
msgstr "Betalingsbewijs"
#: pretix/plugins/stripe/templates/pretixplugins/stripe/oauth_disconnect.html:12
msgid "Do you really want to disconnect your Stripe account?"

View File

@@ -7,8 +7,8 @@ msgstr ""
"Project-Id-Version: 1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-04-28 11:08+0000\n"
"PO-Revision-Date: 2025-03-30 16:00+0000\n"
"Last-Translator: Jan Van Haver <jan.van.haver@gmail.com>\n"
"PO-Revision-Date: 2025-05-01 02:00+0000\n"
"Last-Translator: Foxy Hunter <matthias.vancoillie@outlook.com>\n"
"Language-Team: Dutch <https://translate.pretix.eu/projects/pretix/pretix-js/"
"nl/>\n"
"Language: nl\n"
@@ -16,7 +16,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.10.4\n"
"X-Generator: Weblate 5.11.1\n"
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
@@ -34,28 +34,28 @@ msgstr "PayPal"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:35
msgid "Venmo"
msgstr ""
msgstr "Venmo"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:36
#: pretix/static/pretixpresale/js/walletdetection.js:38
msgid "Apple Pay"
msgstr ""
msgstr "Apple Pay"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:37
msgid "Itaú"
msgstr ""
msgstr "Itaú"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:38
msgid "PayPal Credit"
msgstr ""
msgstr "PayPal-krediet"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:39
msgid "Credit Card"
msgstr ""
msgstr "Kredietkaart"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:40
msgid "PayPal Pay Later"
msgstr ""
msgstr "PayPal Pay Later"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:41
msgid "iDEAL"
@@ -75,7 +75,7 @@ msgstr "giropay"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:45
msgid "SOFORT"
msgstr ""
msgstr "SOFORT"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:46
msgid "eps"
@@ -83,51 +83,51 @@ msgstr "eps"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:47
msgid "MyBank"
msgstr ""
msgstr "MyBank"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:48
msgid "Przelewy24"
msgstr ""
msgstr "Przelewy24"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:49
msgid "Verkkopankki"
msgstr ""
msgstr "Verkkopankki"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:50
msgid "PayU"
msgstr ""
msgstr "PayU"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:51
msgid "BLIK"
msgstr ""
msgstr "BLIK"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:52
msgid "Trustly"
msgstr ""
msgstr "Trustly"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:53
msgid "Zimpler"
msgstr ""
msgstr "Zimpler"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:54
msgid "Maxima"
msgstr ""
msgstr "Maxima"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:55
msgid "OXXO"
msgstr ""
msgstr "OXXO"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:56
msgid "Boleto"
msgstr ""
msgstr "Boleto"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:57
msgid "WeChat Pay"
msgstr ""
msgstr "WeChat Pay"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:58
msgid "Mercado Pago"
msgstr ""
msgstr "Mercado Pago"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:167
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:50
@@ -145,7 +145,7 @@ msgstr "Betaling bevestigen …"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:254
msgid "Payment method unavailable"
msgstr ""
msgstr "Betaalmethode niet beschikbaar"
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:15
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:39
@@ -236,11 +236,11 @@ msgstr "Geannuleerd"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:46
msgid "Confirmed"
msgstr ""
msgstr "Bevestigd"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:47
msgid "Approval pending"
msgstr ""
msgstr "Goedkeuring in afwachting"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:48
msgid "Redeemed"
@@ -296,14 +296,12 @@ msgid "Ticket code revoked/changed"
msgstr "Ticketcode ingetrokken/veranderd"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:63
#, fuzzy
msgid "Ticket blocked"
msgstr "Ticket niet betaald"
msgstr "Ticket geblokkeerd"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:64
#, fuzzy
msgid "Ticket not valid at this time"
msgstr "Ticket niet betaald"
msgstr "Ticket is op dit moment niet geldig"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:65
msgid "Order canceled"
@@ -440,7 +438,7 @@ msgstr "is na"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:40
msgid "="
msgstr ""
msgstr "="
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:99
msgid "Product"
@@ -460,11 +458,11 @@ msgstr "Huidige datum en tijd"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:115
msgid "Current day of the week (1 = Monday, 7 = Sunday)"
msgstr ""
msgstr "Huidige dag van de week (1 = Maandag, 7 = Zondag)"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:119
msgid "Current entry status"
msgstr ""
msgstr "Huidige toegangstatus"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:123
msgid "Number of previous entries"
@@ -475,36 +473,32 @@ msgid "Number of previous entries since midnight"
msgstr "Aantal eerdere binnenkomsten sinds middernacht"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:131
#, fuzzy
msgid "Number of previous entries since"
msgstr "Aantal eerdere binnenkomsten"
msgstr "Aantal eerdere binnenkomsten sinds"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:135
#, fuzzy
msgid "Number of previous entries before"
msgstr "Aantal eerdere binnenkomsten"
msgstr "Aantal eerdere binnenkomsten voor"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:139
msgid "Number of days with a previous entry"
msgstr "Aantal dagen met een eerdere binnenkomst"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:143
#, fuzzy
msgid "Number of days with a previous entry since"
msgstr "Aantal dagen met een eerdere binnenkomst"
msgstr "Aantal dagen met een eerdere binnenkomst sinds"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:147
#, fuzzy
msgid "Number of days with a previous entry before"
msgstr "Aantal dagen met een eerdere binnenkomst"
msgstr "Aantal dagen met een eerdere binnenkomst voor"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:151
msgid "Minutes since last entry (-1 on first entry)"
msgstr ""
msgstr "Minuten sinds laatste toegang (-1 bij eerste toegang)"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:155
msgid "Minutes since first entry (-1 on first entry)"
msgstr ""
msgstr "Minuten sinds de eerste toegang (-1 bij eerste toegang)"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:182
msgid "All of the conditions below (AND)"
@@ -548,17 +542,17 @@ msgstr "minuten"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:192
msgid "Duplicate"
msgstr ""
msgstr "duplicaat"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:193
msgctxt "entry_status"
msgid "present"
msgstr ""
msgstr "aanwezig"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:194
msgctxt "entry_status"
msgid "absent"
msgstr ""
msgstr "afwezig"
#: pretix/static/pretixcontrol/js/ui/editor.js:171
msgid "Check-in QR"
@@ -573,9 +567,8 @@ msgid "Group of objects"
msgstr "Groep van objecten"
#: pretix/static/pretixcontrol/js/ui/editor.js:908
#, fuzzy
msgid "Text object (deprecated)"
msgstr "Tekstobject"
msgstr "Tekstobject (verouderd)"
#: pretix/static/pretixcontrol/js/ui/editor.js:910
msgid "Text box"
@@ -662,11 +655,11 @@ msgstr "Alleen geselecteerde"
#: pretix/static/pretixcontrol/js/ui/main.js:820
msgid "Enter page number between 1 and %(max)s."
msgstr ""
msgstr "voer een pagina nummer tussen 1 en %(max)s in."
#: pretix/static/pretixcontrol/js/ui/main.js:823
msgid "Invalid page number."
msgstr ""
msgstr "Ongeldig pagina nummer."
#: pretix/static/pretixcontrol/js/ui/main.js:981
msgid "Use a different name internally"
@@ -752,22 +745,22 @@ msgstr "Uw lokale tijd:"
#: pretix/static/pretixpresale/js/walletdetection.js:39
msgid "Google Pay"
msgstr ""
msgstr "Google Pay"
#: pretix/static/pretixpresale/js/widget/widget.js:16
msgctxt "widget"
msgid "Quantity"
msgstr ""
msgstr "Aantal"
#: pretix/static/pretixpresale/js/widget/widget.js:17
msgctxt "widget"
msgid "Decrease quantity"
msgstr ""
msgstr "Verlaag aantal"
#: pretix/static/pretixpresale/js/widget/widget.js:18
msgctxt "widget"
msgid "Increase quantity"
msgstr ""
msgstr "Verhoog aantal"
#: pretix/static/pretixpresale/js/widget/widget.js:19
msgctxt "widget"
@@ -778,19 +771,18 @@ msgstr "Prijs"
#, javascript-format
msgctxt "widget"
msgid "Original price: %s"
msgstr ""
msgstr "Originele prijs: %s"
#: pretix/static/pretixpresale/js/widget/widget.js:21
#, javascript-format
msgctxt "widget"
msgid "New price: %s"
msgstr ""
msgstr "Nieuwe prijs: %s"
#: pretix/static/pretixpresale/js/widget/widget.js:22
#, fuzzy
msgctxt "widget"
msgid "Select"
msgstr "Alleen geselecteerde"
msgstr "Selecteer"
#: pretix/static/pretixpresale/js/widget/widget.js:23
#, javascript-format
@@ -838,7 +830,7 @@ msgstr "vanaf %(currency)s %(price)s"
#, javascript-format
msgctxt "widget"
msgid "Image of %s"
msgstr ""
msgstr "Afbeelding van %s"
#: pretix/static/pretixpresale/js/widget/widget.js:32
msgctxt "widget"
@@ -873,21 +865,19 @@ msgstr "Alleen verkrijgbaar met een voucher"
#: pretix/static/pretixpresale/js/widget/widget.js:38
#: pretix/static/pretixpresale/js/widget/widget.js:41
#, fuzzy
msgctxt "widget"
msgid "Not yet available"
msgstr "momenteel beschikbaar: %s"
msgstr "Nog niet beschikbaar"
#: pretix/static/pretixpresale/js/widget/widget.js:39
msgctxt "widget"
msgid "Not available anymore"
msgstr ""
msgstr "Niet langer beschikbaar"
#: pretix/static/pretixpresale/js/widget/widget.js:40
#, fuzzy
msgctxt "widget"
msgid "Currently not available"
msgstr "momenteel beschikbaar: %s"
msgstr "Momenteel niet beschikbaar"
#: pretix/static/pretixpresale/js/widget/widget.js:42
#, javascript-format
@@ -920,12 +910,9 @@ msgid "Open ticket shop"
msgstr "Open de ticketwinkel"
#: pretix/static/pretixpresale/js/widget/widget.js:48
#, fuzzy
#| msgctxt "widget"
#| msgid "Resume checkout"
msgctxt "widget"
msgid "Checkout"
msgstr "Doorgaan met afrekenen"
msgstr "Afrekenen"
#: pretix/static/pretixpresale/js/widget/widget.js:49
msgctxt "widget"
@@ -989,16 +976,14 @@ msgid "Continue"
msgstr "Ga verder"
#: pretix/static/pretixpresale/js/widget/widget.js:61
#, fuzzy
msgctxt "widget"
msgid "Show variants"
msgstr "Zie variaties"
msgstr "Toon varianten"
#: pretix/static/pretixpresale/js/widget/widget.js:62
#, fuzzy
msgctxt "widget"
msgid "Hide variants"
msgstr "Zie variaties"
msgstr "Verberg varianten"
#: pretix/static/pretixpresale/js/widget/widget.js:63
msgctxt "widget"
@@ -1047,6 +1032,9 @@ msgid ""
"add yourself to the waiting list. We will then notify if seats are available "
"again."
msgstr ""
"Sommige of alle tiketcategorieën zijn op heden uitverkocht. Als je wilt, kun "
"je jezelf toevoegen aan de wachtlijst. We zullen je informeren wanneer er "
"weer plaatsen beschikbaar zijn."
#: pretix/static/pretixpresale/js/widget/widget.js:72
msgctxt "widget"
@@ -1083,31 +1071,31 @@ msgstr "Zo"
#: pretix/static/pretixpresale/js/widget/widget.js:81
msgid "Monday"
msgstr ""
msgstr "Maandag"
#: pretix/static/pretixpresale/js/widget/widget.js:82
msgid "Tuesday"
msgstr ""
msgstr "Dinsdag"
#: pretix/static/pretixpresale/js/widget/widget.js:83
msgid "Wednesday"
msgstr ""
msgstr "Woensdag"
#: pretix/static/pretixpresale/js/widget/widget.js:84
msgid "Thursday"
msgstr ""
msgstr "Donderdag"
#: pretix/static/pretixpresale/js/widget/widget.js:85
msgid "Friday"
msgstr ""
msgstr "Vrijdag"
#: pretix/static/pretixpresale/js/widget/widget.js:86
msgid "Saturday"
msgstr ""
msgstr "Zaterdag"
#: pretix/static/pretixpresale/js/widget/widget.js:87
msgid "Sunday"
msgstr ""
msgstr "Zondag"
#: pretix/static/pretixpresale/js/widget/widget.js:90
msgid "January"

View File

@@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-04-28 11:06+0000\n"
"PO-Revision-Date: 2025-02-21 19:00+0000\n"
"Last-Translator: anonymous <noreply@weblate.org>\n"
"PO-Revision-Date: 2025-05-06 16:20+0000\n"
"Last-Translator: KC Tseng <tkc0204@gmail.com>\n"
"Language-Team: Chinese (Traditional Han script) <https://translate.pretix.eu/"
"projects/pretix/pretix/zh_Hant/>\n"
"Language: zh_Hant\n"
@@ -17,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Weblate 5.10\n"
"X-Generator: Weblate 5.11.1\n"
#: pretix/_base_settings.py:87
msgid "English"
@@ -57,7 +57,7 @@ msgstr "捷克語"
#: pretix/_base_settings.py:96
msgid "Croatian"
msgstr ""
msgstr "克羅埃西亞語"
#: pretix/_base_settings.py:97
msgid "Danish"
@@ -2910,11 +2910,9 @@ msgid "Repeat password"
msgstr "重複"
#: pretix/base/forms/questions.py:134 pretix/base/forms/questions.py:256
#, fuzzy
#| msgid "No country specified."
msgctxt "name_salutation"
msgid "not specified"
msgstr "未指定國家/地區。"
msgstr "未指定"
#: pretix/base/forms/questions.py:219
msgid "Please do not use special characters in names."
@@ -3980,10 +3978,8 @@ msgid "Grant type"
msgstr "授權類型"
#: pretix/base/models/customers.py:420
#, fuzzy
#| msgid "Required question"
msgid "Require PKCE extension"
msgstr "必填題"
msgstr "需要交換驗證碼用的驗證密鑰(PKCE)擴充功能"
#: pretix/base/models/customers.py:432
msgid "Allowed access scopes"
@@ -4139,12 +4135,9 @@ msgstr ""
"產品僅限於例如解鎖隱藏產品或獲得售罄配額仍可享折扣。"
#: pretix/base/models/discount.py:177
#, fuzzy
#| msgctxt "subevent"
#| msgid "All dates starting before"
msgctxt "subevent"
msgid "Available for dates starting from"
msgstr "之前開始的所有日期"
msgstr "適用日期始於"
#: pretix/base/models/discount.py:182
#, fuzzy
@@ -5333,18 +5326,12 @@ msgid "Unknown country code."
msgstr "未知國家代碼."
#: pretix/base/models/items.py:1921 pretix/base/models/items.py:1923
#, fuzzy
#| msgid "The maximum count needs to be greater than the minimum count."
msgid "The maximum date must not be before the minimum value."
msgstr "最大計數需要大於最小計數。"
msgstr "最大日期不得早於最小。"
#: pretix/base/models/items.py:1925
#, fuzzy
#| msgid ""
#| "The maximum number of usages may not be lower than the minimum number of "
#| "usages."
msgid "The maximum value must not be lower than the minimum value."
msgstr "最大使用次數,不得低於最小使用次數。"
msgstr "最大不得低於最小。"
#: pretix/base/models/items.py:1942
#: pretix/control/templates/pretixcontrol/items/question.html:90
@@ -6738,11 +6725,9 @@ msgid "The payment for this invoice has already been received."
msgstr "此發票的付款已收到。"
#: pretix/base/payment.py:970
#, fuzzy
#| msgid "This payment can not be canceled at the moment."
msgid ""
"This payment is already being processed and can not be canceled any more."
msgstr "此付款目前無法取消。"
msgstr "此付款已在處理中,無法取消。"
#: pretix/base/payment.py:984
msgid "Automatic refunds are not supported by this payment provider."
@@ -7087,7 +7072,7 @@ msgstr "活動從工作日開始"
#: pretix/base/pdf.py:266 pretix/base/pdf.py:295
#: pretix/base/services/checkin.py:362 pretix/control/forms/filter.py:1240
msgid "Friday"
msgstr "星期五"
msgstr "五"
#: pretix/base/pdf.py:270
msgid "Event end date and time"
@@ -7762,27 +7747,27 @@ msgstr "工作日"
#: pretix/base/services/checkin.py:358 pretix/control/forms/filter.py:1236
msgid "Monday"
msgstr "星期一"
msgstr "一"
#: pretix/base/services/checkin.py:359 pretix/control/forms/filter.py:1237
msgid "Tuesday"
msgstr "星期二"
msgstr "二"
#: pretix/base/services/checkin.py:360 pretix/control/forms/filter.py:1238
msgid "Wednesday"
msgstr "星期三"
msgstr "三"
#: pretix/base/services/checkin.py:361 pretix/control/forms/filter.py:1239
msgid "Thursday"
msgstr "星期四"
msgstr "四"
#: pretix/base/services/checkin.py:363 pretix/control/forms/filter.py:1241
msgid "Saturday"
msgstr "星期六"
msgstr "六"
#: pretix/base/services/checkin.py:364 pretix/control/forms/filter.py:1242
msgid "Sunday"
msgstr "星期天"
msgstr "週日"
#: pretix/base/services/checkin.py:368
#, python-brace-format
@@ -9315,6 +9300,9 @@ msgid ""
"page. Note that pretix still is a system built around events and the date "
"may still show up in other places."
msgstr ""
"如果您僅出售無特定日期的物品(例如:禮品卡或可隨時使用的門票),請取消勾選此"
"方塊。系統將停止在某些地方活動開始頁面顯示活動日期。請注意pretix "
"仍然是一個圍繞建立活動的系統,日期可能仍會出現在其他地方。"
#: pretix/base/settings.py:1326
msgid "Show event end date"
@@ -10920,13 +10908,6 @@ msgid "Header image"
msgstr "標題圖像"
#: pretix/base/settings.py:2885
#, fuzzy
#| msgid ""
#| "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 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."
msgid ""
"If you provide a logo image, we will by default not show your event name and "
"date in the page header. If you use a white background, we show your logo "
@@ -10934,9 +10915,10 @@ msgid ""
"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."
msgstr ""
"如果你提供徽章標誌圖片,默認情況下,我們不會在頁中顯示您的活動名稱和日期。"
"默認情況下我們顯示的徽標大小最大為1140x120圖元。您可以使用以下設置增加大"
"小。我們建議不要在圖片上使用小細節,因為它將在較小的螢幕上調整大小。"
"如果你提供標誌圖片,預設情況下,我們不會在頁中顯示您的活動名稱和日期。如果"
"您使用白色背景的標誌我們顯示標誌尺寸最大為1140x120像素其餘情況的最大尺寸"
"為您1120x120像素。您可以使用下列設定擴大尺寸。我們建議不要在圖片上使用小細節"
",因為它的尺寸將在較小的螢幕被調整。"
#: pretix/base/settings.py:2906 pretix/base/settings.py:2949
msgid "Use header image in its full size"
@@ -10960,13 +10942,6 @@ msgstr ""
"的標題圖像,則將忽略此選項,並始終顯示活動標題。"
#: pretix/base/settings.py:2929 pretix/control/forms/organizer.py:524
#, fuzzy
#| msgid ""
#| "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 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."
msgid ""
"If you provide a logo image, we will by default not show your organization "
"name in the page header. If you use a white background, we show your logo "
@@ -10974,10 +10949,11 @@ msgid ""
"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."
msgstr ""
"如果你提供徽章標誌圖片,預設情況下,我們不會在頁面抬頭中顯示你的活動名稱和"
"日期。預設值情況下我們顯示的徽章標誌圖片大小最大為1140x120圖元。你可以使用"
"以下設置增加大小。我們建議不要在圖片上使用小細節,因為圖片將在較小的螢幕上調"
"整大小。"
"如果你提供標誌圖片,預設情況下,我們不會在頁中顯示你的活動名稱和日期。如果"
"你使用白色背景我們顯示的標誌尺寸最大為1140x120像素。否則最大尺寸為 "
"1120x120 "
"像素。你可以使用下列設定增加大小。我們建議不要在圖片上使用小細節,因為圖片將"
"在較小的螢幕上調整尺寸。"
#: pretix/base/settings.py:2959
msgid "Use header image also for events without an individually uploaded logo"
@@ -11352,18 +11328,14 @@ msgid "MA"
msgstr "MA"
#: pretix/base/settings.py:3722 pretix/base/settings.py:3724
#, fuzzy
#| msgid "Provider name"
msgctxt "address"
msgid "Province"
msgstr "提供者名稱"
msgstr ""
#: pretix/base/settings.py:3723
#, fuzzy
#| msgid "Price effect"
msgctxt "address"
msgid "Prefecture"
msgstr "價格效應"
msgstr "縣/州/區"
#: pretix/base/settings.py:3812 pretix/control/forms/event.py:228
msgid ""
@@ -13372,7 +13344,7 @@ msgstr "小冊子磁磚屬性"
#: pretix/control/forms/global_settings.py:103
msgid "ApplePay MerchantID Domain Association"
msgstr ""
msgstr "ApplePay 網域憑證驗證"
#: pretix/control/forms/global_settings.py:104
#, python-brace-format
@@ -13798,7 +13770,8 @@ msgid ""
"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})."
msgstr ""
msgstr "密碼包含我們電子郵件系統不支援的字元。僅接受字元 A-Z、a-z、0-9 "
"和常見的特殊字元 ({characters})。"
#: pretix/control/forms/mailsetup.py:70
msgid "Use STARTTLS"
@@ -14132,7 +14105,7 @@ msgstr "收件人"
#, fuzzy, python-brace-format
#| msgid "Attach ticket files"
msgid "Attach {file}"
msgstr "附加票證檔"
msgstr "附件{files}"
#: pretix/control/forms/orders.py:796
msgid ""
@@ -14448,7 +14421,7 @@ msgstr "電話欄位"
#: pretix/control/forms/organizer.py:1048
msgctxt "sso_oidc"
msgid "Query parameters"
msgstr ""
msgstr "查詢參數"
#: pretix/control/forms/organizer.py:1049
#, python-brace-format
@@ -14456,7 +14429,7 @@ msgctxt "sso_oidc"
msgid ""
"Optional query parameters, that will be added to calls to the authorization "
"endpoint. Enter as: {example}"
msgstr ""
msgstr "可選查詢參數,將被加入到對授權端的呼叫。輸入為:{example}"
#: pretix/control/forms/organizer.py:1110
msgid "Invalidate old client secret and generate a new one"
@@ -16770,20 +16743,14 @@ msgid "Delete check-ins"
msgstr "刪除簽到"
#: pretix/control/templates/pretixcontrol/checkin/bulk_revert_confirm.html:15
#, fuzzy, python-format
#| msgid ""
#| "Are you sure you want to permanently delete the check-ins of <strong>one "
#| "ticket</strong>."
#| msgid_plural ""
#| "Are you sure you want to permanently delete the check-ins of "
#| "<strong>%(count)s tickets</strong>?"
#, python-format
msgid ""
"Are you sure you want to permanently delete the check-ins of <strong>one "
"ticket</strong>?"
msgid_plural ""
"Are you sure you want to permanently delete the check-ins of "
"<strong>%(count)s tickets</strong>?"
msgstr[0] "你確定要永久刪除<strong>%(count)s 張票</strong>的簽到清單嗎?"
msgstr[0] "你確定要永久刪除<strong>%(count)s 張票</strong>的報到紀錄嗎?"
#: pretix/control/templates/pretixcontrol/checkin/bulk_revert_confirm.html:24
#: pretix/control/templates/pretixcontrol/checkin/list_delete.html:18
@@ -17443,6 +17410,18 @@ msgid ""
"Best regards, \n"
"Your %(instance)s team\n"
msgstr ""
"你好,\n"
"\n"
"偵測到有人從不尋常或新位置登入您的 %(instance)s 帳戶。登入是在 %(country)s "
"使用 %(os)s 系統的 %(agent)s 執行。\n"
"\n"
"如果這是您,您可以放心忽略這封電子郵件。\n"
"\n"
"如果這不是您本人,我們建議您在帳戶設定中變更密碼:\n"
"\n"
"%(url)s\n"
"\n"
"%(instance)s 團隊 敬上\n"
#: pretix/control/templates/pretixcontrol/email/security_notice.txt:1
#, python-format
@@ -18209,10 +18188,8 @@ msgid "Disabled"
msgstr "禁用"
#: pretix/control/templates/pretixcontrol/event/payment.html:57
#, fuzzy
#| msgid "Enable waiting list"
msgid "Enable additional payment plugins"
msgstr "啟動候補名單"
msgstr "啟用其他支付外掛"
#: pretix/control/templates/pretixcontrol/event/payment.html:66
msgid "Deadlines"
@@ -18308,10 +18285,8 @@ msgid "Your changes have been saved."
msgstr "你的更改已儲存。"
#: pretix/control/templates/pretixcontrol/event/plugins.html:34
#, fuzzy
#| msgid "Check results"
msgid "Search results"
msgstr "檢查結果"
msgstr "搜尋結果"
#: pretix/control/templates/pretixcontrol/event/plugins.html:56
msgid "Top recommendation"
@@ -18331,16 +18306,12 @@ msgstr "無法使用"
#: pretix/control/templates/pretixcontrol/event/plugins.html:93
#: pretix/control/templates/pretixcontrol/event/plugins.html:105
#, fuzzy
#| msgid "Login settings"
msgid "Open plugin settings"
msgstr "登錄設定"
msgstr "開啟外掛設定"
#: pretix/control/templates/pretixcontrol/event/plugins.html:94
#, fuzzy
#| msgid "Go to shop"
msgid "Go to"
msgstr "到商店"
msgstr "前往"
#: pretix/control/templates/pretixcontrol/event/plugins.html:116
#: pretix/control/templates/pretixcontrol/oauth/app_delete.html:15
@@ -19143,18 +19114,21 @@ msgid ""
"If you have a pretix Enterprise license, this report must be submitted to "
"pretix support when your license renews. It may also be requested by pretix "
"support to aid debugging of problems."
msgstr ""
msgstr "如果您擁有 "
"Pretix企業版許可證必須在許可證續約時將此報告提交給pretix支援團隊。 pretix "
"支援人員可能會要求以協助調試問題。"
#: pretix/control/templates/pretixcontrol/global_sysreport.html:8
msgid ""
"It serves two purposes: Collecting useful information that might help with "
"debugging problems in your pretix installation, and verifying that your "
"usage of pretix is in compliance with the Enterprise license you purchased."
msgstr ""
msgstr "它有兩個目的:收集可能有助於調試 pretix 安裝中問題的有用資訊,"
"以及驗證您使用pretix 時是否符合您購買的企業許可證。"
#: pretix/control/templates/pretixcontrol/global_sysreport.html:14
msgid "First month of license term:"
msgstr ""
msgstr "許可期限的第一個月:"
#: pretix/control/templates/pretixcontrol/global_sysreport.html:16
msgid "January"
@@ -19477,10 +19451,10 @@ msgstr "是否確實要刪除商品<strong>%(item)s</strong>"
#: pretix/control/templates/pretixcontrol/item/delete.html:22
#: pretix/control/templates/pretixcontrol/items/quota_delete.html:24
#, fuzzy, python-format
#, python-format
msgid "That will cause %(count)s voucher to be unusable."
msgid_plural "That will cause %(count)s voucher to be unusable."
msgstr[0] "這將導致%(count)s優惠券不可用.這將導致 %(count)s的優惠券不可用."
msgstr[0] "這將導致%(count)s優惠券無法使用。"
#: pretix/control/templates/pretixcontrol/item/delete.html:29
#: pretix/control/templates/pretixcontrol/items/quota_delete.html:31
@@ -19861,20 +19835,13 @@ msgid "taxes"
msgstr "稅"
#: pretix/control/templates/pretixcontrol/items/index.html:10
#, fuzzy
#| msgid ""
#| "Below, you find a list of all available products. You can click on a "
#| "product name to inspect and change product details. You can also use the "
#| "buttons on the right to change the order of products within a give "
#| "category."
msgid ""
"Below, you find a list of all available products. You can click on a product "
"name to inspect and change product details. You can also use the buttons on "
"the right to change the order of products or move products to a different "
"category."
msgstr ""
"下面,你可以找到所有可用產品的清單。你可以按下產品名稱來檢查和更改產品詳細資"
"訊。你還可以使用右側的按鈕更改給定類別中產品的順序。"
msgstr "下面,你可以找到所有可用產品的清單。你可以按下產品名稱來檢查和更改產品詳細資"
"訊。你也可使用右側按鈕變更產品順序或將其移至其他類別。"
#: pretix/control/templates/pretixcontrol/items/index.html:19
msgid "You haven't created any products yet."

View File

@@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-04-28 11:08+0000\n"
"PO-Revision-Date: 2025-01-31 01:00+0000\n"
"Last-Translator: Chislon <chislon@gmail.com>\n"
"PO-Revision-Date: 2025-05-06 16:20+0000\n"
"Last-Translator: KC Tseng <tkc0204@gmail.com>\n"
"Language-Team: Chinese (Traditional Han script) <https://translate.pretix.eu/"
"projects/pretix/pretix-js/zh_Hant/>\n"
"Language: zh_Hant\n"
@@ -17,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Weblate 5.9.2\n"
"X-Generator: Weblate 5.11.1\n"
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
@@ -669,10 +669,8 @@ msgid "Calculating default price…"
msgstr "計算預設價格…"
#: pretix/static/pretixcontrol/js/ui/plugins.js:69
#, fuzzy
#| msgid "Search results"
msgid "No results"
msgstr "搜尋結果"
msgstr "結果"
#: pretix/static/pretixcontrol/js/ui/question.js:42
msgid "Others"
@@ -898,12 +896,9 @@ msgid "Open ticket shop"
msgstr "開放售票"
#: pretix/static/pretixpresale/js/widget/widget.js:48
#, fuzzy
#| msgctxt "widget"
#| msgid "Resume checkout"
msgctxt "widget"
msgid "Checkout"
msgstr "繼續結帳"
msgstr "結帳"
#: pretix/static/pretixpresale/js/widget/widget.js:49
msgctxt "widget"
@@ -1058,31 +1053,31 @@ msgstr "星期天"
#: pretix/static/pretixpresale/js/widget/widget.js:81
msgid "Monday"
msgstr ""
msgstr "週一"
#: pretix/static/pretixpresale/js/widget/widget.js:82
msgid "Tuesday"
msgstr ""
msgstr "週二"
#: pretix/static/pretixpresale/js/widget/widget.js:83
msgid "Wednesday"
msgstr ""
msgstr "週三"
#: pretix/static/pretixpresale/js/widget/widget.js:84
msgid "Thursday"
msgstr ""
msgstr "週四"
#: pretix/static/pretixpresale/js/widget/widget.js:85
msgid "Friday"
msgstr ""
msgstr "週五"
#: pretix/static/pretixpresale/js/widget/widget.js:86
msgid "Saturday"
msgstr ""
msgstr "週六"
#: pretix/static/pretixpresale/js/widget/widget.js:87
msgid "Sunday"
msgstr ""
msgstr "週日"
#: pretix/static/pretixpresale/js/widget/widget.js:90
msgid "January"

View File

@@ -1,8 +1,7 @@
.banktransfer-swiss-cross-overlay {
position: relative;
width: 150px;
height: 150px;
margin: 0 auto 10px;
margin: 0 auto;
}
.banktransfer-swiss-cross {
position: absolute;

View File

@@ -44,34 +44,28 @@
</p>
</div>
{% if settings.bank_details_type == "sepa" and any_barcodes %}
<div class="col-md-6 col-sm-6 hidden-xs text-center js-only blank-after">
<ul class="nav nav-tabs" id="banktransfer_qrcodes_tabs" role="tablist">
<div class="tabcontainer col-md-6 col-sm-6 hidden-xs text-center js-only blank-after">
<div id="banktransfer_qrcodes_tabs_content" class="tabpanels blank-after">
{% if swiss_qrbill %}
<li class="active"><a href="#banktransfer_qrcodes_qrbill" role="tab" id="banktransfer_qrcodes_qrbill_tab" data-toggle="tab" aria-controls="banktransfer_qrcodes_qrbill" aria-expanded="true">QR-bill</a></li>
{% endif %}
{% if eu_barcodes %}
<li {% if not swiss_qrbill %}class="active"{% endif %}><a href="#banktransfer_qrcodes_girocode" role="tab" id="banktransfer_qrcodes_girocode_tab" data-toggle="tab" aria-controls="banktransfer_qrcodes_girocode" aria-expanded="{% if swiss_qrbill %}false{% else %}true{% endif %}">EPC-QR</a></li>
<li class=""><a href="#banktransfer_qrcodes_bezahlcode" role="tab" id="banktransfer_qrcodes_bezahlcode_tab" data-toggle="tab" aria-controls="banktransfer_qrcodes_bezahlcode" aria-expanded="false">BezahlCode</a></li>
{% endif %}
</ul>
<div class="tab-content" id="banktransfer_qrcodes_tabs_content">
{% if swiss_qrbill %}
<div id="banktransfer_qrcodes_qrbill" class="tab-pane fade active in" role="tabpanel" aria-labelledby="banktransfer_qrcodes_qrbill_tab">
<p class="small">
{% trans "Scan the qr-code with your banking app" %}
</p>
<p class="banktransfer-swiss-cross-overlay">
<div id="banktransfer_qrcodes_qrbill"
role="tabpanel"
tabindex="0"
aria-labelledby="banktransfer_qrcodes_qrbill_tab"
>
<div class="banktransfer-swiss-cross-overlay" role="figure" aria-labelledby="banktransfer_qrcodes_qrbill_tab banktransfer_qrcodes_label">
<svg class="banktransfer-swiss-cross" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 19.8 19.8"><path stroke="#fff" stroke-width="1.436" d="M.7.7h18.4v18.4H.7z"/><path fill="#fff" d="M8.3 4h3.3v11H8.3z"/><path fill="#fff" d="M4.4 7.9h11v3.3h-11z"/></svg>
<script type="text/plain" data-size="150" data-replace-with-qr data-desc="{% trans 'Scan this image with your banking apps QR-Reader to start the payment process.' %}">{{swiss_qrbill}}</script>
</p>
</div>
</div>
{% endif %}
{% if eu_barcodes %}
<div id="banktransfer_qrcodes_girocode" class="tab-pane fade {% if not swiss_qrbill %}active in{% endif %}" role="tabpanel" aria-labelledby="banktransfer_qrcodes_girocode_tab">
<p class="small">
{% trans "Scan the qr-code with your banking app" %}
</p>
<p>
<div id="banktransfer_qrcodes_girocode"
role="tabpanel"
tabindex="0"
{{ swiss_qrbill|yesno:'hidden,' }}
aria-labelledby="banktransfer_qrcodes_girocode_tab"
>
<div role="figure" aria-labelledby="banktransfer_qrcodes_girocode_tab banktransfer_qrcodes_label">
<script type="text/plain" data-size="150" data-replace-with-qr data-desc="{% trans 'Scan this image with your banking apps QR-Reader to start the payment process.' %}">BCD
002
2
@@ -85,20 +79,55 @@ SCT
{{ code }}
</script>
</p>
</div>
</div>
<div id="banktransfer_qrcodes_bezahlcode" class="tab-pane fade" role="tabpanel" aria-labelledby="banktransfer_qrcodes_bezahlcode_tab">
<p class="small">
{% trans "Scan the qr-code with your banking app" %}
</p>
<p>
<a aria-label="{% trans "Open BezahlCode in your banking app to start the payment process." %}" href="bank://singlepaymentsepa?name={{ settings.bank_details_sepa_name|urlencode }}&iban={{ settings.bank_details_sepa_iban }}&bic={{ settings.bank_details_sepa_bic }}&amount={{ amount|commadecimal }}&reason={{ code }}&currency={{ event.currency }}">
<div id="banktransfer_qrcodes_bezahlcode"
role="tabpanel"
tabindex="0"
hidden
aria-labelledby="banktransfer_qrcodes_bezahlcode_tab"
>
<a aria-label="{% trans "Open BezahlCode in your banking app to start the payment process." %}" href="bank://singlepaymentsepa?name={{ settings.bank_details_sepa_name|urlencode }}&iban={{ settings.bank_details_sepa_iban }}&bic={{ settings.bank_details_sepa_bic }}&amount={{ amount|commadecimal }}&reason={{ code }}&currency={{ event.currency }}">
<div role="figure" aria-labelledby="banktransfer_qrcodes_bezahlcode_tab banktransfer_qrcodes_label">
<script type="text/plain" data-size="150" data-replace-with-qr data-desc="{% trans 'Scan this image with your banking apps QR-Reader to start the payment process.' %}">bank://singlepaymentsepa?name={{ settings.bank_details_sepa_name|urlencode }}&iban={{ settings.bank_details_sepa_iban }}&bic={{ settings.bank_details_sepa_bic }}&amount={{ amount|commadecimal }}&reason={{ code }}&currency={{ event.currency }}</script>
</a>
</p>
</div>
</a>
</div>
{% endif %}
</div>
<div id="banktransfer_qrcodes_tabs" role="tablist" aria-labelledby="banktransfer_qrcodes_label" class="blank-after btn-group">
{% if swiss_qrbill %}
<button
class="btn btn-default"
id="banktransfer_qrcodes_qrbill_tab"
type="button"
role="tab"
aria-controls="banktransfer_qrcodes_qrbill"
aria-selected="true"
tabindex="-1">QR-bill</button>
{% endif %}
{% if eu_barcodes %}
<button
class="btn btn-default"
id="banktransfer_qrcodes_girocode_tab"
type="button"
role="tab"
aria-controls="banktransfer_qrcodes_girocode"
aria-selected="{{ swiss_qrbill|yesno:"false,true" }}"
tabindex="-1">EPC-QR</button>
<button
class="btn btn-default"
id="banktransfer_qrcodes_bezahlcode_tab"
type="button"
role="tab"
aria-controls="banktransfer_qrcodes_bezahlcode"
aria-selected="false"
tabindex="-1">BezahlCode</button>
{% endif %}
</div>
<p class="text-muted" id="banktransfer_qrcodes_label">
{% trans "Scan the QR code with your banking app" %}
</p>
</div>
{% endif %}
</div>
@@ -142,4 +171,4 @@ SCT
</div>
</form>
<hr>
{% endif %}
{% endif %}

View File

@@ -801,7 +801,13 @@ class CheckinLogList(ListExporter):
ia = ci.position.order.invoice_address
except InvoiceAddress.DoesNotExist:
ia = InvoiceAddress()
name = (
ci.position.attendee_name or
(ci.position.addon_to.attendee_name if ci.position.addon_to else '') or
ia.name
)
else:
name = ""
yield [
date_format(ci.datetime.astimezone(self.timezone), 'SHORT_DATE_FORMAT'),
date_format(ci.datetime.astimezone(self.timezone), 'TIME_FORMAT'),
@@ -811,7 +817,7 @@ class CheckinLogList(ListExporter):
ci.position.positionid if ci.position else '',
ci.raw_barcode or ci.position.secret,
str(ci.position.item) if ci.position else (str(ci.raw_item) if ci.raw_item else ''),
(ci.position.attendee_name or ia.name) if ci.position else '',
name,
str(ci.device) if ci.device else '',
_('Yes') if ci.force_sent is True else (_('No') if ci.force_sent is False else '?'),
_('Yes') if ci.forced else _('No'),

View File

@@ -44,6 +44,7 @@ from pretix.base.forms.questions import (
from pretix.base.i18n import get_language_without_region
from pretix.base.models import Customer
from pretix.helpers.http import get_client_ip
from pretix.multidomain.urlreverse import build_absolute_uri
class TokenGenerator(PasswordResetTokenGenerator):
@@ -68,16 +69,24 @@ class AuthenticationForm(forms.Form):
'invalid_login': _(
"We have not found an account with this email address and password."
),
'invalid_login_email': _('Please verify that you entered the correct email addess.'),
'invalid_login_password': _('Please enter the correct password.'),
'inactive': _("This account is disabled."),
'unverified': _("You have not yet activated your account and set a password. Please click the link in the "
"email we sent you. Click \"Reset password\" to receive a new email in case you cannot find "
"it again."),
"email we sent you. In case you cannot find it, click \"Forgot your password?\" to receive "
"a new email."),
}
def __init__(self, request=None, *args, **kwargs):
self.request = request
self.customer_cache = None
super().__init__(*args, **kwargs)
self.fields['password'].help_text = "<a href='{}'>{}</a>".format(
build_absolute_uri(False, 'presale:organizer.customer.resetpw', kwargs={
'organizer': request.organizer.slug,
}),
_('Forgot your password?')
)
def clean(self):
email = self.cleaned_data.get('email')
@@ -94,6 +103,8 @@ class AuthenticationForm(forms.Form):
if u.check_password(password):
self.customer_cache = u
if self.customer_cache is None:
self.add_error("email", self.error_messages['invalid_login_email'])
self.add_error("password", self.error_messages['invalid_login_password'])
raise forms.ValidationError(
self.error_messages['invalid_login'],
code='invalid_login',
@@ -110,15 +121,9 @@ class AuthenticationForm(forms.Form):
def confirm_login_allowed(self, user):
if not user.is_active:
raise forms.ValidationError(
self.error_messages['inactive'],
code='inactive',
)
if not user.is_verified:
raise forms.ValidationError(
self.error_messages['unverified'],
code='unverified',
)
self.add_error("email", self.error_messages['inactive'])
elif not user.is_verified:
self.add_error("password", self.error_messages['unverified'])
def get_customer(self):
return self.customer_cache

View File

@@ -33,6 +33,7 @@ def render_label(content, label_for=None, label_class=None, label_title='', labe
"""
Render a label with content
"""
tag = 'label'
attrs = attrs or {}
if label_for:
attrs['for'] = label_for
@@ -58,15 +59,16 @@ def render_label(content, label_for=None, label_class=None, label_title='', labe
attrs['class'] += ' label-empty'
# usually checkboxes have overall empty labels and special labels per checkbox
# => remove for-attribute as well as "required"-text appended to label
tag = 'div'
if 'for' in attrs:
del attrs['for']
elif not optional:
opt += '<i class="sr-only label-required">, {}</i>'.format(pgettext('form', 'required'))
opt += '<i class="label-required">{}</i>'.format(pgettext('form', 'required'))
builder = '<{tag}{attrs}>{content}{opt}</{tag}>'
return format_html(
builder,
tag='label',
tag=tag,
attrs=mark_safe(flatatt(attrs)) if attrs else '',
opt=mark_safe(opt),
content=text_value(content),

View File

@@ -44,6 +44,9 @@
</head>
<body class="nojs" data-locale="{{ request.LANGUAGE_CODE }}" data-now="{% now "U.u" %}" data-datetimeformat="{{ js_datetime_format }}" data-timeformat="{{ js_time_format }}" data-dateformat="{{ js_date_format }}" data-datetimelocale="{{ js_locale }}" data-currency="{{ request.event.currency }}">
{{ html_page_header|safe }}
<nav id="skip-to-main" role="navigation" aria-label="{% trans "Skip link" context "skip-to-main-nav" %}" class="sr-only on-focus-visible">
<p><a href="#content">{% trans "Skip to main content" %}</a></p>
</nav>
<header>
{% if ie_deprecation_warning %}
<div class="old-browser-warning">

View File

@@ -13,7 +13,7 @@
{% endblock %}
{% block content %}
<aside aria-label="{% trans "Your cart" %}">
<details class="panel panel-default cart{% if "open_cart" not in request.GET %} sneak-peek{% endif %}" {% if "open_cart" in request.GET %}open{% endif %}>
<details class="panel panel-default cart sneak-peek-container" open>
<summary class="panel-heading">
<h2 class="panel-title">
<span>
@@ -33,11 +33,15 @@
</summary>
{% if "open_cart" not in request.GET %}
<p class="sneak-peek-trigger">
<button type="button" class="btn btn-default">{% trans "Show full cart" %}</button>
<button type="button" class="btn btn-default" aria-controls="cart-foldable-container">{% trans "Show full cart" %}</button>
</p>
{% endif %}
<div>
{% if "open_cart" not in request.GET %}
<div class="panel-body sneak-peek-content" id="cart-foldable-container">
{% else %}
<div class="panel-body">
{% endif %}
{% include "pretixpresale/event/fragment_cart.html" with cart=cart event=request.event %}
</div>
</div>

View File

@@ -11,31 +11,31 @@
<h2>{% trans "Review order" %}</h2>
{% include "pretixpresale/event/fragment_checkoutflow.html" %}
<p>{% trans "Please review the details below and confirm your order." %}</p>
<div class="panel panel-primary cart">
<div class="panel-heading panel-heading-flex">
<h3 class="panel-title">
<i class="fa fa-shopping-cart" aria-hidden="true"></i>
{% trans "Your cart" %}
<a href="{% eventurl request.event "presale:event.index" cart_namespace=cart_namespace|default_if_none:"" %}" class="h6">
<span class="fa fa-edit" aria-hidden="true"></span>{% trans "Add or remove tickets" %}
</a>
</h3>
<span class="panel-heading-flex-gap"></span>
<strong class="helper-display-block" id="cart-deadline-short" data-expires="{{ cart.first_expiry|date:"Y-m-d H:i:sO" }}">
{% if cart.minutes_left > 0 or cart.seconds_left > 0 %}
{{ cart.minutes_left|stringformat:"02d" }}:{{ cart.seconds_left|stringformat:"02d" }}
{% else %}
{% trans "Cart expired" %}
{% endif %}
</strong>
</div>
<div class="panel-body">
{% include "pretixpresale/event/fragment_cart.html" with cart=cart event=request.event editable=False %}
</div>
</div>
<form method="post" data-asynctask
data-asynctask-headline="{% trans "Please hang tight, we're finalizing your order!" %}">
{% csrf_token %}
<div class="panel panel-primary cart">
<div class="panel-heading panel-heading-flex">
<h3 class="panel-title">
<i class="fa fa-shopping-cart" aria-hidden="true"></i>
{% trans "Your cart" %}
<a href="{% eventurl request.event "presale:event.index" cart_namespace=cart_namespace|default_if_none:"" %}" class="h6">
<span class="fa fa-edit" aria-hidden="true"></span>{% trans "Add or remove tickets" %}
</a>
</h3>
<span class="panel-heading-flex-gap"></span>
<strong class="helper-display-block" id="cart-deadline-short" data-expires="{{ cart.first_expiry|date:"Y-m-d H:i:sO" }}">
{% if cart.minutes_left > 0 or cart.seconds_left > 0 %}
{{ cart.minutes_left|stringformat:"02d" }}:{{ cart.seconds_left|stringformat:"02d" }}
{% else %}
{% trans "Cart expired" %}
{% endif %}
</strong>
</div>
<div class="panel-body">
{% include "pretixpresale/event/fragment_cart.html" with cart=cart event=request.event editable=False %}
</div>
</div>
{% if payments %}
<div class="panel panel-default">
<div class="panel-heading">

View File

@@ -48,15 +48,6 @@
</p>
{% if request.organizer.settings.customer_accounts_native %}
{% bootstrap_form login_form layout="checkout" %}
<div class="row">
<div class="col-md-offset-3 col-md-9">
<a
href="{% abseventurl request.organizer "presale:organizer.customer.resetpw" %}"
target="_blank">
{% trans "Reset password" %}
</a>
</div>
</div>
{% endif %}
<div class="row">
<div class="col-md-6 col-md-offset-3">

View File

@@ -23,10 +23,7 @@
{% trans "Seat" %}
</label>
<div class="col-md-9 form-control-text">
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="14" viewBox="0 0 4.7624999 3.7041668" class="svg-icon">
<path
d="m 1.9592032,1.8522629e-4 c -0.21468,0 -0.38861,0.17394000371 -0.38861,0.38861000371 0,0.21466 0.17393,0.38861 0.38861,0.38861 0.21468,0 0.3886001,-0.17395 0.3886001,-0.38861 0,-0.21467 -0.1739201,-0.38861000371 -0.3886001,-0.38861000371 z m 0.1049,0.84543000371 c -0.20823,-0.0326 -0.44367,0.12499 -0.39998,0.40462997 l 0.20361,1.01854 c 0.0306,0.15316 0.15301,0.28732 0.3483,0.28732 h 0.8376701 v 0.92708 c 0,0.29313 0.41187,0.29447 0.41187,0.005 v -1.19115 c 0,-0.14168 -0.0995,-0.29507 -0.29094,-0.29507 l -0.65578,-10e-4 -0.1757,-0.87644 C 2.3042533,0.95300523 2.1890432,0.86500523 2.0641032,0.84547523 Z m -0.58549,0.44906997 c -0.0946,-0.0134 -0.20202,0.0625 -0.17829,0.19172 l 0.18759,0.91054 c 0.0763,0.33956 0.36802,0.55914 0.66042,0.55914 h 0.6015201 c 0.21356,0 0.21448,-0.32143 -0.003,-0.32143 H 2.1954632 c -0.19911,0 -0.36364,-0.11898 -0.41341,-0.34107 l -0.17777,-0.87126 c -0.0165,-0.0794 -0.0688,-0.11963 -0.12557,-0.12764 z"/>
</svg>
{% include "icons/seat.svg" with cls="svg-icon" %}
{{ form.position.seat }}
</div>
</div>

View File

@@ -6,11 +6,6 @@
{% load escapejson %}
{% block inner %}
<p>{% trans "Before we continue, we need you to answer some questions." %}</p>
<p class="required-legend" aria-hidden="true">
{% blocktrans trimmed %}
You need to fill all fields that are marked with <span>*</span> to continue.
{% endblocktrans %}
</p>
{% if profiles_data %}
{{ profiles_data|json_script:"profiles_json" }}
{% endif %}
@@ -100,10 +95,7 @@
{% trans "Seat" %}
</label>
<div class="col-md-9 form-control-text">
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="14" viewBox="0 0 4.7624999 3.7041668" class="svg-icon">
<path
d="m 1.9592032,1.8522629e-4 c -0.21468,0 -0.38861,0.17394000371 -0.38861,0.38861000371 0,0.21466 0.17393,0.38861 0.38861,0.38861 0.21468,0 0.3886001,-0.17395 0.3886001,-0.38861 0,-0.21467 -0.1739201,-0.38861000371 -0.3886001,-0.38861000371 z m 0.1049,0.84543000371 c -0.20823,-0.0326 -0.44367,0.12499 -0.39998,0.40462997 l 0.20361,1.01854 c 0.0306,0.15316 0.15301,0.28732 0.3483,0.28732 h 0.8376701 v 0.92708 c 0,0.29313 0.41187,0.29447 0.41187,0.005 v -1.19115 c 0,-0.14168 -0.0995,-0.29507 -0.29094,-0.29507 l -0.65578,-10e-4 -0.1757,-0.87644 C 2.3042533,0.95300523 2.1890432,0.86500523 2.0641032,0.84547523 Z m -0.58549,0.44906997 c -0.0946,-0.0134 -0.20202,0.0625 -0.17829,0.19172 l 0.18759,0.91054 c 0.0763,0.33956 0.36802,0.55914 0.66042,0.55914 h 0.6015201 c 0.21356,0 0.21448,-0.32143 -0.003,-0.32143 H 2.1954632 c -0.19911,0 -0.36364,-0.11898 -0.41341,-0.34107 l -0.17777,-0.87126 c -0.0165,-0.0794 -0.0688,-0.11963 -0.12557,-0.12764 z"/>
</svg>
{% include "icons/seat.svg" with cls="svg-icon" %}
{{ pos.seat }}
</div>
</div>

View File

@@ -205,7 +205,7 @@
{% else %}
<fieldset class="input-item-count-group" aria-describedby="c-{{ form.pos.pk }}-{{ category_idx }}-addon-count-desc cp-{{ form.pos.pk }}-item-{{ item.pk }}-min-order">
<legend class="sr-only">{% blocktrans with item=item.name %}Add {{ item }}, {{ var }} to cart{% endblocktrans %}</legend>
<button type="button" data-step="-1" data-controls="cp_{{ form.pos.pk }}_variation_{{ item.id }}_{{ var.id }}" class="btn btn-default input-item-count-dec" aria-label="{% trans "Decrease quantity" %}">-</button>
<button type="button" data-step="-1" data-controls="cp_{{ form.pos.pk }}_variation_{{ item.id }}_{{ var.id }}" class="btn btn-default input-item-count-dec" aria-label="- {{ item }}, {{ var }}: {% trans "Decrease quantity" %}">-</button>
<input type="number" class="form-control input-item-count" placeholder="0" min="0"
{% if var.initial %}value="{{ var.initial }}"{% endif %}
{% if item.free_price %}
@@ -215,7 +215,7 @@
id="cp_{{ form.pos.pk }}_variation_{{ item.id }}_{{ var.id }}"
name="cp_{{ form.pos.pk }}_variation_{{ item.id }}_{{ var.id }}"
aria-label="{% trans "Quantity" %}">
<button type="button" data-step="1" data-controls="cp_{{ form.pos.pk }}_variation_{{ item.id }}_{{ var.id }}" class="btn btn-default input-item-count-inc" aria-label="{% trans "Increase quantity" %}">+</button>
<button type="button" data-step="1" data-controls="cp_{{ form.pos.pk }}_variation_{{ item.id }}_{{ var.id }}" class="btn btn-default input-item-count-inc" aria-label="+ {{ item }}, {{ var }}: {% trans "Increase quantity" %}">+</button>
</fieldset>
{% endif %}
</div>
@@ -351,7 +351,7 @@
{% else %}
<fieldset class="input-item-count-group" aria-describedby="c-{{ form.pos.pk }}-{{ category_idx }}-addon-count-desc cp-{{ form.pos.pk }}-item-{{ item.pk }}-min-order">
<legend class="sr-only">{% blocktrans with item=item.name %}Add {{ item }} to cart{% endblocktrans %}</legend>
<button type="button" data-step="-1" data-controls="cp_{{ form.pos.pk }}_item_{{ item.id }}" class="btn btn-default input-item-count-dec" aria-label="{% trans "Decrease quantity" %}">-</button>
<button type="button" data-step="-1" data-controls="cp_{{ form.pos.pk }}_item_{{ item.id }}" class="btn btn-default input-item-count-dec" aria-label="- {{ item }}: {% trans "Decrease quantity" %}">-</button>
<input type="number" class="form-control input-item-count" placeholder="0" min="0"
{% if item.free_price %}
data-checked-onchange="price-item-{{ form.pos.pk }}-{{ item.pk }}"
@@ -361,7 +361,7 @@
name="cp_{{ form.pos.pk }}_item_{{ item.id }}"
id="cp_{{ form.pos.pk }}_item_{{ item.id }}"
aria-label="{% trans "Quantity" %}">
<button type="button" data-step="1" data-controls="cp_{{ form.pos.pk }}_item_{{ item.id }}" class="btn btn-default input-item-count-inc" aria-label="{% trans "Increase quantity" %}">+</button>
<button type="button" data-step="1" data-controls="cp_{{ form.pos.pk }}_item_{{ item.id }}" class="btn btn-default input-item-count-inc" aria-label="+ {{ item }}: {% trans "Increase quantity" %}">+</button>
</fieldset>
{% endif %}
</div>

View File

@@ -11,8 +11,11 @@
<span role="columnheader" aria-sort="none">{% trans "Product" %}</span>
{% if download %}
<span role="columnheader" aria-sort="none">{% trans "Ticket download" %}</span>
{% elif not hide_prices %}
<span role="columnheader" aria-sort="none">{% trans "Price per item" %}</span>
{% else %}
<span role="columnheader" aria-sort="none">{% trans "Quantity" %}</span>
{% if not hide_prices %}
<span role="columnheader" aria-sort="none">{% trans "Price per item" %}</span>
{% endif %}
{% endif %}
{% if not hide_prices %}
<span role="columnheader" aria-sort="none">{% trans "Price total" %}</span>
@@ -41,11 +44,8 @@
<div class="cart-icon-details">
<dt class="sr-only">{% trans "Seat:" %}</dt>
<dd>
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="14" viewBox="0 0 4.7624999 3.7041668" class="svg-icon">
<path
d="m 1.9592032,1.8522629e-4 c -0.21468,0 -0.38861,0.17394000371 -0.38861,0.38861000371 0,0.21466 0.17393,0.38861 0.38861,0.38861 0.21468,0 0.3886001,-0.17395 0.3886001,-0.38861 0,-0.21467 -0.1739201,-0.38861000371 -0.3886001,-0.38861000371 z m 0.1049,0.84543000371 c -0.20823,-0.0326 -0.44367,0.12499 -0.39998,0.40462997 l 0.20361,1.01854 c 0.0306,0.15316 0.15301,0.28732 0.3483,0.28732 h 0.8376701 v 0.92708 c 0,0.29313 0.41187,0.29447 0.41187,0.005 v -1.19115 c 0,-0.14168 -0.0995,-0.29507 -0.29094,-0.29507 l -0.65578,-10e-4 -0.1757,-0.87644 C 2.3042533,0.95300523 2.1890432,0.86500523 2.0641032,0.84547523 Z m -0.58549,0.44906997 c -0.0946,-0.0134 -0.20202,0.0625 -0.17829,0.19172 l 0.18759,0.91054 c 0.0763,0.33956 0.36802,0.55914 0.66042,0.55914 h 0.6015201 c 0.21356,0 0.21448,-0.32143 -0.003,-0.32143 H 2.1954632 c -0.19911,0 -0.36364,-0.11898 -0.41341,-0.34107 l -0.17777,-0.87126 c -0.0165,-0.0794 -0.0688,-0.11963 -0.12557,-0.12764 z"/>
</svg>
{{ line.seat }}
{% include "icons/seat.svg" with cls="svg-icon" %}
{{ line.seat }}
</dd>
</div>
{% endif %}
@@ -392,12 +392,20 @@
{% endfor %}
{% endfor %}
{% for fee in cart.fees %}
<div class="row cart-row">
<div class="col-md-4 col-xs-6">
<div role="row" class="row cart-row">
<div role="cell" class="col-md-4 col-xs-6">
<strong>{{ fee.get_fee_type_display }}</strong>
</div>
{% if download %}
<div role="cell"></div>
{% else %}
<div role="cell"></div>
{% if not hide_prices %}
<div role="cell"></div>
{% endif %}
{% endif %}
{% if not hide_prices %}
<div class="col-md-3 col-xs-6 col-md-offset-5 price">
<div role="cell" class="col-md-3 col-xs-6 col-md-offset-5 price">
{% if event.settings.display_net_prices %}
<strong>{{ fee.net_value|money:event.currency }}</strong>
{% if fee.tax_rate %}
@@ -484,15 +492,21 @@
<div class="row">
<div class="col-md-12">
{% if not cart.is_ordered %}
<p class="text-muted" id="cart-deadline" data-expires="{{ cart.first_expiry|date:"Y-m-d H:i:sO" }}">
{% if cart.minutes_left > 0 or cart.seconds_left > 0 %}
{% blocktrans trimmed with minutes=cart.minutes_left %}
The items in your cart are reserved for you for {{ minutes }} minutes.
{% endblocktrans %}
{% else %}
{% trans "The items in your cart are no longer reserved for you. You can still complete your order as long as theyre available." %}
{% endif %}
</p>
<form class="text-muted" id="cart-extend-form" data-asynctask data-asynctask-no-redirect
method="post" action="{% eventurl request.event "presale:event.cart.extend" cart_namespace=cart_namespace %}">
{% csrf_token %}
<span id="cart-deadline" data-expires="{{ cart.first_expiry|date:"Y-m-d H:i:sO" }}" data-max-expiry-extend="{{ cart.max_expiry_extend|date:"Y-m-d H:i:sO" }}">
{% if cart.minutes_left > 0 or cart.seconds_left > 0 %}
{% blocktrans trimmed with minutes=cart.minutes_left %}
The items in your cart are reserved for you for {{ minutes }} minutes.
{% endblocktrans %}
{% else %}
{% trans "The items in your cart are no longer reserved for you. You can still complete your order as long as theyre available." %}
{% endif %}
</span>
<button class="btn btn-link" type="submit" id="cart-extend-button">
<i class="fa fa-refresh" aria-hidden="true"></i> {% trans "Extend" %}</button>
</form>
{% else %}
<p class="sr-only" id="cart-description">{% trans "Overview of your ordered products." %}</p>
{% endif %}

View File

@@ -7,7 +7,7 @@
{% load rich_text %}
{% for tup in items_by_category %}{% with category=tup.0 items=tup.1 form_prefix=tup.2 %}
{% if category %}
<section aria-labelledby="{{ form_prefix }}category-{{ category.id }}"{% if category.description %} aria-describedby="{{ form_prefix }}category-info-{{ category.id }}"{% endif %}>
<section class="item-category" aria-labelledby="{{ form_prefix }}category-{{ category.id }}"{% if category.description %} aria-describedby="{{ form_prefix }}category-info-{{ category.id }}"{% endif %}>
<h{{ headline_level|default:3 }} class="h3" id="{{ form_prefix }}category-{{ category.id }}">{{ category.name }}
{% if category.subevent_name %}
<small class="text-muted"><i class="fa fa-calendar" aria-hidden="true"></i> {{ category.subevent_name }}</small>
@@ -24,7 +24,7 @@
<div id="{{ form_prefix }}category-info-{{ category.id }}">{{ category.description|localize|rich_text }}</div>
{% endif %}
{% else %}
<section aria-labelledby="{{ form_prefix }}category-none">
<section class="item-category" aria-labelledby="{{ form_prefix }}category-none">
<h{{ headline_level|default:"3" }} id="{{ form_prefix }}category-none" class="h3 sr-only">{% trans "Uncategorized items" %}</h{{ headline_level|default:3 }}>
{% endif %}
{% for item in items %}
@@ -221,7 +221,7 @@
{% else %}
<fieldset class="input-item-count-group">
<legend class="sr-only">{% blocktrans with item=item.name %}Add {{ item }}, {{ var }} to cart{% endblocktrans %}</legend>
<button type="button" data-step="-1" data-controls="{{ form_prefix }}variation_{{ item.id }}_{{ var.id }}" class="btn btn-default input-item-count-dec" aria-label="{% trans "Decrease quantity" %}"
<button type="button" data-step="-1" data-controls="{{ form_prefix }}variation_{{ item.id }}_{{ var.id }}" class="btn btn-default input-item-count-dec" aria-label="- {{ item }}, {{ var }}: {% trans "Decrease quantity" %}"
{% if not ev.presale_is_running %}disabled{% endif %}>-</button>
<input type="number" class="form-control input-item-count" placeholder="0" min="0"
{% if not ev.presale_is_running %}disabled{% endif %}
@@ -232,7 +232,7 @@
id="{{ form_prefix }}variation_{{ item.id }}_{{ var.id }}"
name="{{ form_prefix }}variation_{{ item.id }}_{{ var.id }}"
aria-label="{% trans "Quantity" %}">
<button type="button" data-step="1" data-controls="{{ form_prefix }}variation_{{ item.id }}_{{ var.id }}" class="btn btn-default input-item-count-inc" aria-label="{% trans "Increase quantity" %}"
<button type="button" data-step="1" data-controls="{{ form_prefix }}variation_{{ item.id }}_{{ var.id }}" class="btn btn-default input-item-count-inc" aria-label="+ {{ item }}, {{ var }}: {% trans "Increase quantity" %}"
{% if not ev.presale_is_running %}disabled{% endif %}>+</button>
</fieldset>
{% endif %}
@@ -262,7 +262,7 @@
</a>
{% endif %}
<div class="product-description {% if item.picture %}with-picture{% endif %}">
<h{{ headline_level|default:3|add:1 }} class="h4" id="{{ form_prefix }}item-{{ item.pk }}-legend">{{ item.name }}</h{{ headline_level|default:3 }}>
<h{{ headline_level|default:3|add:1 }} class="h4" id="{{ form_prefix }}item-{{ item.pk }}-legend">{{ item.name }}</h{{ headline_level|default:3|add:1 }}>
{% if item.description %}
<div id="{{ form_prefix }}item-{{ item.pk }}-description" class="product-description">
{{ item.description|localize|rich_text }}
@@ -373,7 +373,7 @@
{% else %}
<fieldset class="input-item-count-group">
<legend class="sr-only">{% blocktrans with item=item.name %}Add {{ item }} to cart{% endblocktrans %}</legend>
<button type="button" data-step="-1" data-controls="{{ form_prefix }}item_{{ item.id }}" class="btn btn-default input-item-count-dec" aria-label="{% trans "Decrease quantity" %}"
<button type="button" data-step="-1" data-controls="{{ form_prefix }}item_{{ item.id }}" class="btn btn-default input-item-count-dec" aria-label="- {{ item }}: {% trans "Decrease quantity" %}"
{% if not ev.presale_is_running %}disabled{% endif %}>-</button>
<input type="number" class="form-control input-item-count" placeholder="0" min="0"
{% if not ev.presale_is_running %}disabled{% endif %}
@@ -385,7 +385,7 @@
name="{{ form_prefix }}item_{{ item.id }}"
id="{{ form_prefix }}item_{{ item.id }}"
aria-label="{% trans "Quantity" %}">
<button type="button" data-step="1" data-controls="{{ form_prefix }}item_{{ item.id }}" class="btn btn-default input-item-count-inc" aria-label="{% trans "Increase quantity" %}"
<button type="button" data-step="1" data-controls="{{ form_prefix }}item_{{ item.id }}" class="btn btn-default input-item-count-inc" aria-label="+ {{ item }}: {% trans "Increase quantity" %}"
{% if not ev.presale_is_running %}disabled{% endif %}>+</button>
</fieldset>
{% endif %}

View File

@@ -1,44 +1,55 @@
{% load i18n %}
{% load eventurl %}
{% load icon %}
{% load urlreplace %}
<nav aria-label="{% trans "calendar navigation" %}">
<ul class="row calendar-nav">
<li class="col-sm-4 col-xs-2 text-left flip">
<li class="text-left flip">
{% if subevent_list.has_before %}
<a href="?{% url_replace request "date" subevent_list.before|date:"Y-m" %}"
class="btn btn-default" data-save-scrollpos aria-label="{% blocktrans with month=subevent_list.before|date:"F Y" %}Show previous month, {{ month }}{% endblocktrans %}">
<span class="fa fa-arrow-left" aria-hidden="true"></span>
{% icon "arrow-left" %}
<span class="hidden-xs">{{ subevent_list.before|date:"F Y" }}</span>
</a>
{% endif %}
</li>
<li class="col-sm-4 col-xs-8 text-center">
<li class="text-center">
<form class="form-inline" method="get" id="monthselform" action="{% eventurl event "presale:event.index" cart_namespace=cart_namespace %}">
{% for f, v in request.GET.items %}
{% if f != "date" %}
<input type="hidden" name="{{ f }}" value="{{ v }}">
{% endif %}
{% endfor %}
<select name="date" class="form-control" aria-label="{% trans "Select month to show" %}">
{% for y in subevent_list.years %}
<optgroup label="{{ y }}">
{% for m in subevent_list.months %}
<option value="{{ y }}-{{ m|date:"m" }}" {% if m.month == subevent_list.date.month and y == subevent_list.date.year %}selected{% endif %}>{{ m|date:"F" }} {{ y }}</option>
{% endfor %}
</optgroup>
{% endfor %}
</select>
<button type="submit" class="js-hidden btn btn-default">
{% trans "Go" %}
</button>
<fieldset>
<legend class="sr-only">{% trans "Select a month to display" %}</legend>
<div>
<label for="calendar-input-date">{% trans "Month" %}</label>
</div>
<div class="input-group">
<select name="date" class="form-control" id="calendar-input-date">
{% for y in subevent_list.years %}
<optgroup label="{{ y }}">
{% for m in subevent_list.months %}
<option value="{{ y }}-{{ m|date:"m" }}" {% if m.month == subevent_list.date.month and y == subevent_list.date.year %}selected{% endif %}>{{ m|date:"F" }} {{ y }}</option>
{% endfor %}
</optgroup>
{% endfor %}
</select>
<span class="input-group-btn">
<button type="submit" class="btn btn-default" aria-label="{% trans "Show month" %}">
{% icon "chevron-right" %}
</button>
</span>
</div>
</fieldset>
</form>
</li>
<li class="col-sm-4 col-xs-2 text-right flip">
<li class="text-right flip">
{% if subevent_list.has_after %}
<a href="?{% url_replace request "date" subevent_list.after|date:"Y-m" %}"
class="btn btn-default" data-save-scrollpos aria-label="{% blocktrans with month=subevent_list.after|date:"F Y" %}Show next month, {{ month }}{% endblocktrans %}">
<span class="hidden-xs">{{ subevent_list.after|date:"F Y" }}</span>
<span class="fa fa-arrow-right" aria-hidden="true"></span>
{% icon "arrow-right" %}
</a>
{% endif %}
</li>

View File

@@ -1,63 +1,78 @@
{% load i18n %}
{% load eventurl %}
{% load icon %}
{% load urlreplace %}
<nav aria-label="{% trans "calendar navigation" %}">
<ul class="row calendar-nav">
<li class="col-sm-4 col-xs-2 text-left flip">
<li class="text-left flip">
{% if subevent_list.has_before %}
<a href="?{% url_replace request "date" subevent_list.before|date:"o-\WW" %}"
class="btn btn-default" data-save-scrollpos aria-label="{% blocktrans with week=subevent_list.before|date:subevent_list.week_format %}Show previous week, {{ week }}{% endblocktrans %}">
<span class="fa fa-arrow-left" aria-hidden="true"></span>
{% icon "arrow-left" %}
<span class="hidden-xs">{{ subevent_list.before|date:subevent_list.week_format }}</span>
</a>
{% endif %}
</li>
<li class="col-sm-4 col-xs-8 text-center">
<li class="text-center">
<form class="form-inline" method="get" id="monthselform" action="{% eventurl event "presale:event.index" cart_namespace=cart_namespace %}">
{% for f, v in request.GET.items %}
{% if f != "date" %}
<input type="hidden" name="{{ f }}" value="{{ v }}">
{% endif %}
{% endfor %}
<select name="date" class="form-control" aria-label="{% trans "Select week to show" %}">
{% for weeks_per_year in subevent_list.weeks %}
<optgroup label="{{ weeks_per_year.0.0.year }}">
{% for w in weeks_per_year %}
<option value="{{ w.0.isocalendar.0 }}-W{{ w.0.isocalendar.1 }}"
{% if w.0.isocalendar.0 == subevent_list.date.isocalendar.0 and w.0.isocalendar.1 == subevent_list.date.isocalendar.1 %}selected{% endif %}>
{{ w.0|date:subevent_list.week_format }}
({{ w.0|date:subevent_list.short_month_day_format }} {{ w.1|date:subevent_list.short_month_day_format }})
</option>
{% endfor %}
</optgroup>
{% for f, v in request.GET.items %}
{% if f != "date" %}
<input type="hidden" name="{{ f }}" value="{{ v }}">
{% endif %}
{% endfor %}
</select>
<button type="submit" class="js-hidden btn btn-default">
{% trans "Go" %}
</button>
<fieldset>
<legend class="sr-only">{% trans "Select a week to display" %}</legend>
<div>
<label for="calendar-input-date">{% trans "Week" %}</label>
</div>
<div class="input-group">
<select name="date" class="form-control" aria-label="{% trans "Select week to show" %}">
{% for weeks_per_year in subevent_list.weeks %}
<optgroup label="{{ weeks_per_year.0.0.year }}">
{% for w in weeks_per_year %}
<option value="{{ w.0.isocalendar.0 }}-W{{ w.0.isocalendar.1 }}"
{% if w.0.isocalendar.0 == subevent_list.date.isocalendar.0 and w.0.isocalendar.1 == subevent_list.date.isocalendar.1 %}selected{% endif %}>
{{ w.0|date:subevent_list.week_format }}
({{ w.0|date:subevent_list.short_month_day_format }} {{ w.1|date:subevent_list.short_month_day_format }})
</option>
{% endfor %}
</optgroup>
{% endfor %}
</select>
<span class="input-group-btn">
<button type="submit" class="btn btn-default" aria-label="{% trans "Show week" %}">
{% icon "chevron-right" %}
</button>
</span>
</div>
</fieldset>
</form>
</li>
<li class="col-sm-4 col-xs-2 text-right flip">
<li class="text-right flip">
{% if subevent_list.has_after %}
<a href="?{% url_replace request "date" subevent_list.after|date:"o-\WW" %}"
class="btn btn-default" data-save-scrollpos aria-label="{% blocktrans with week=subevent_list.after|date:subevent_list.week_format %}Show next week, {{ week }}{% endblocktrans %}">
<span class="hidden-xs">{{ subevent_list.after|date:subevent_list.week_format }}</span>
<span class="fa fa-arrow-right" aria-hidden="true"></span>
{% icon "arrow-right" %}
</a>
{% endif %}
</li>
</ul>
</nav>
{% include "pretixpresale/fragment_week_calendar.html" with show_avail=event.settings.event_list_availability days=subevent_list.days show_names=subevent_list.show_names %}
<div class="visible-xs text-center" aria-hidden="true">
<a href="?{% url_replace request "date" subevent_list.before|date:"o-\WW" %}"
class="btn btn-default" data-save-scrollpos aria-label="{% blocktrans with week=subevent_list.before|date:subevent_list.week_format %}Show previous week, {{ week }}{% endblocktrans %}">
<span class="fa fa-arrow-left" aria-hidden="true"></span>
{{ subevent_list.before|date:subevent_list.week_format }}
</a>
<a href="?{% url_replace request "date" subevent_list.after|date:"o-\WW" %}"
class="btn btn-default" data-save-scrollpos aria-label="{% blocktrans with week=subevent_list.after|date:subevent_list.week_format %}Show next week, {{ week }}{% endblocktrans %}">
{{ subevent_list.after|date:subevent_list.week_format }}
<span class="fa fa-arrow-right" aria-hidden="true"></span>
</a>
<div class="row visible-xs">
<div class="col-xs-6 text-left flip">
<a href="?{% url_replace request "date" subevent_list.before|date:"o-\WW" %}"
class="btn btn-default" data-save-scrollpos aria-label="{% blocktrans with week=subevent_list.before|date:subevent_list.week_format %}Show previous week, {{ week }}{% endblocktrans %}">
<span class="fa fa-arrow-left" aria-hidden="true"></span>
<span class="hidden-xs">{{ subevent_list.before|date:subevent_list.week_format }}</span>
</a>
</div>
<div class="col-xs-6 text-right flip">
<a href="?{% url_replace request "date" subevent_list.after|date:"o-\WW" %}"
class="btn btn-default" data-save-scrollpos aria-label="{% blocktrans with week=subevent_list.after|date:subevent_list.week_format %}Show next week, {{ week }}{% endblocktrans %}">
<span class="hidden-xs">{{ subevent_list.after|date:subevent_list.week_format }}</span>
<span class="fa fa-arrow-right" aria-hidden="true"></span>
</a>
</div>
</div>

View File

@@ -16,6 +16,7 @@
<br>
<span data-time="{{ subev.date_from.isoformat }}" data-timezone="{{ event.timezone }}" data-time-short>
{% icon "clock-o" %}
<span class="sr-only">{% trans "Time of day" %}</span>
<time datetime="{{ subev.date_from.isoformat }}">{{ subev.date_from|date:"TIME_FORMAT" }}</time>
</span>
{% endif %}

View File

@@ -71,14 +71,15 @@
{% endif %}
{% if subevent_list_foldable %}
<details class="panel panel-{% if show_cart %}primary{% else %}default{% endif %}">
<summary class="panel-heading">
{% else %}
<div class="panel panel-default">
<div class="panel-heading">
{% endif %}
<h3 class="panel-title"><b>
{% if subevent_list.list_type != "list" or subevent_list.visible_events %}
{% if subevent_list_foldable %}
<details class="panel panel-{% if show_cart %}primary{% else %}default{% endif %}">
<summary class="panel-heading">
{% else %}
<div class="panel panel-default">
<div class="panel-heading">
{% endif %}
<h3 class="panel-title"><strong>
{% if subevent_list_foldable %}
{% if show_cart %}
{% trans "Add tickets for a different date" %}
@@ -87,36 +88,37 @@
{% endif %}
{% else %}
{% trans "Choose date to book a ticket" %}
{% endif %}</b>
</h3>
{% if subevent_list_foldable %}
</summary>
<div>
{% else %}
</div>
{% endif %}
{% endif %}</strong>
</h3>
{% if subevent_list_foldable %}
</summary>
<div>
{% else %}
</div>
{% endif %}
{% if filter_form.fields %}
<div class="panel-subhead">
{% include "pretixpresale/fragment_event_list_filter.html" with request=request %}
</div>
{% endif %}
<div class="panel-body">
{% cache_large 15 subevent_list subevent_list_cache_key %}
{% if subevent_list.list_type == "calendar" %}
{% include "pretixpresale/event/fragment_subevent_calendar.html" %}
{% elif subevent_list.list_type == "week" %}
{% include "pretixpresale/event/fragment_subevent_calendar_week.html" %}
{% else %}
{% include "pretixpresale/event/fragment_subevent_list.html" %}
{% endif %}
{% endcache_large %}
</div>
{% if subevent_list_foldable %}
<div class="panel-body">
{% cache_large 15 subevent_list subevent_list_cache_key %}
{% if subevent_list.list_type == "calendar" %}
{% include "pretixpresale/event/fragment_subevent_calendar.html" %}
{% elif subevent_list.list_type == "week" %}
{% include "pretixpresale/event/fragment_subevent_calendar_week.html" %}
{% else %}
{% include "pretixpresale/event/fragment_subevent_list.html" %}
{% endif %}
{% endcache_large %}
</div>
</details>
{% else %}
</div>
{% endif %}
{% if subevent_list_foldable %}
</div>
</details>
{% else %}
</div>
{% endif %}
{% endif %}
{% if subevent %}
<h2 class="subevent-head">{{ subevent.name }}</h2>

View File

@@ -10,15 +10,13 @@
<h2>
{% trans "Resend order links" %}
</h2>
<div class="row">
<div class="panel-body">
<p>
{% blocktrans trimmed %}
If you lost the link to your order or orders, please enter the email address you
used for your order. We will send you an email with links to all orders you placed
using this email address.
{% endblocktrans %}
</div>
</div>
</p>
<div class="row">
<form class="form" method="post">
{% csrf_token %}

View File

@@ -233,14 +233,14 @@
{% else %}
<fieldset class="input-item-count-group">
<legend class="sr-only">{% blocktrans with item=item.name %}Add {{ item }}, {{ var }} to cart{% endblocktrans %}</legend>
<button type="button" data-step="-1" data-controls="variation_{{ item.id }}_{{ var.id }}" class="btn btn-default input-item-count-dec" aria-label="{% trans "Decrease quantity" %}">-</button>
<button type="button" data-step="-1" data-controls="variation_{{ item.id }}_{{ var.id }}" class="btn btn-default input-item-count-dec" aria-label="- {{ item }}, {{ var }}: {% trans "Decrease quantity" %}">-</button>
<input type="number" class="form-control input-item-count" placeholder="0" min="0"
max="{{ var.order_max }}"
id="variation_{{ item.id }}_{{ var.id }}"
name="variation_{{ item.id }}_{{ var.id }}"
{% if options == 1 %}value="1"{% endif %}
aria-label="{% trans "Quantity" %}">
<button type="button" data-step="1" data-controls="variation_{{ item.id }}_{{ var.id }}" class="btn btn-default input-item-count-inc" aria-label="{% trans "Increase quantity" %}">+</button>
<button type="button" data-step="1" data-controls="variation_{{ item.id }}_{{ var.id }}" class="btn btn-default input-item-count-inc" aria-label="+ {{ item }}, {{ var }}: {% trans "Increase quantity" %}">+</button>
</fieldset>
{% endif %}
{% else %}
@@ -388,7 +388,7 @@
{% else %}
<fieldset class="input-item-count-group">
<legend class="sr-only">{% blocktrans with item=item.name %}Add {{ item }} to cart{% endblocktrans %}</legend>
<button type="button" data-step="-1" data-controls="item_{{ item.id }}" class="btn btn-default input-item-count-dec" aria-label="{% trans "Decrease quantity" %}">-</button>
<button type="button" data-step="-1" data-controls="item_{{ item.id }}" class="btn btn-default input-item-count-dec" aria-label="- {{ item }}: {% trans "Decrease quantity" %}">-</button>
<input type="number" class="form-control input-item-count"
placeholder="0" min="0"
max="{{ item.order_max }}"
@@ -396,7 +396,7 @@
name="item_{{ item.id }}"
{% if options == 1 %}value="1"{% endif %}
aria-label="{% trans "Quantity" %}">
<button type="button" data-step="1" data-controls="item_{{ item.id }}" class="btn btn-default input-item-count-inc" aria-label="{% trans "Increase quantity" %}">+</button>
<button type="button" data-step="1" data-controls="item_{{ item.id }}" class="btn btn-default input-item-count-inc" aria-label="+ {{ item }}: {% trans "Increase quantity" %}">+</button>
</fieldset>
{% endif %}
{% else %}

View File

@@ -7,7 +7,7 @@
<thead>
<tr>
{% for d in weeks|iter_weekdays %}
<th><span aria-hidden="true">{{ d|date_fast:"D" }}</span><span class="sr-only">{{ d|date_fast:"l" }}</span></th>
<th><span aria-hidden="true" class="text-muted">{{ d|date_fast:"D" }}</span><span class="sr-only">{{ d|date_fast:"l" }}</span></th>
{% endfor %}
</tr>
</thead>

View File

@@ -16,6 +16,7 @@
{% for f in filter_form.fields %}
{% bootstrap_field filter_form|getitem:f %}
{% endfor %}
<div class="visible-xs">&nbsp;</div>
<button type="submit" class="btn btn-primary">
<span class="fa fa-filter" aria-hidden="true"></span>
{% trans "Filter" %}

View File

@@ -10,6 +10,7 @@
<script type="text/javascript" src="{% static "slider/bootstrap-slider.js" %}"></script>
<script type="text/javascript" src="{% static "cropper/cropper.js" %}"></script>
<script type="text/javascript" src="{% static "pretixbase/js/details.js" %}"></script>
<script type="text/javascript" src="{% static "pretixbase/js/dialogs.js" %}"></script>
<script type="text/javascript" src="{% static "pretixcontrol/js/jquery.qrcode.min.js" %}"></script>
<script type="text/javascript" src="{% static "pretixpresale/js/widget/floatformat.js" %}"></script>
<script type="text/javascript" src="{% static "pretixpresale/js/ui/questions.js" %}"></script>

View File

@@ -2,16 +2,17 @@
{% load rich_text %}
{% load safelink %}
{% load escapejson %}
<div id="ajaxerr">
<div id="ajaxerr" class="modal-wrapper" hidden>
</div>
<div id="popupmodal" hidden aria-live="polite">
<div id="popupmodal" class="modal-wrapper" hidden aria-live="polite" role="dialog"
aria-labelledby="popupmodal-title">
<div class="modal-card">
<div class="modal-card-icon">
<i class="fa fa-window-restore big-icon" aria-hidden="true"></i>
</div>
<div class="modal-card-content">
<div>
<h3>
<h3 id="popupmodal-title">
{% trans "We've started the requested process in a new window." %}
</h3>
<p class="text">
@@ -30,27 +31,14 @@
</div>
</div>
</div>
<div id="loadingmodal" hidden aria-live="polite">
<div class="modal-card">
<div class="modal-card-icon">
<i class="fa fa-cog big-rotating-icon" aria-hidden="true"></i>
</div>
<div class="modal-card-content">
<h3 id="loadingmodal-label"></h3>
<div id="loadingmodal-description">
<p class="text"></p>
<p class="status">{% trans "If this takes longer than a few minutes, please contact us." %}</p>
</div>
</div>
</div>
</div>
{% if request.organizer and request.organizer.settings.cookie_consent %}
<script type="text/plain" id="cookie-consent-storage-key">cookie-consent-{{ request.organizer.slug }}</script>
{% if cookie_consent_from_widget %}
{{ cookie_consent_from_widget|json_script:"cookie-consent-from-widget" }}
{% endif %}
{% if cookie_providers %}
<div id="cookie-consent-modal" aria-live="polite">
<div id="cookie-consent-modal" class="modal-wrapper" hidden aria-live="polite" role="dialog"
aria-labelledby="cookie-consent-modal-label">
<div class="modal-card">
<div class="modal-card-content">
<h3 id="cookie-consent-modal-label"></h3>

View File

@@ -1,61 +1,91 @@
{% extends "pretixpresale/organizers/base.html" %}
{% load i18n %}
{% load icon %}
{% load rich_text %}
{% load eventurl %}
{% load urlreplace %}
{% block title %}{% trans "Event overview" %}{% endblock %}
{% block content %}
{% if organizer_homepage_text %}
<div>
<div class="blank-after">
{{ organizer_homepage_text | rich_text }}
</div>
{% endif %}
<h3>{{ date|date:"F Y" }}</h3>
<form class="form-inline" method="get" id="monthselform" action="{% eventurl request.organizer "presale:organizer.index" %}">
{% for f, v in request.GET.items %}
{% if f != "date" %}
<input type="hidden" name="{{ f }}" value="{{ v }}">
{% endif %}
{% endfor %}
<div class="row">
<div class="col-md-5 col-sm-6 col-xs-12 text-left flip">
{% include "pretixpresale/fragment_calendar_nav.html" with date=date request=request style="calendar" %}
</div>
<div class="col-md-2 col-sm-4 col-xs-8 text-center" role="group" aria-label="{% trans "Select month to show" %}">
<select name="date" class="form-control" aria-label="{% trans "Month" %}">
{% for y in years %}
<optgroup label="{{ y }}">
{% for m in months %}
<option value="{{ y }}-{{ m|date:"m" }}" {% if m.month == date.month and y == date.year %}selected{% endif %}>{{ m|date:"F" }} {{ y }}</option>
{% endfor %}
</optgroup>
{% endfor %}
</select>
<button type="submit" class="js-hidden btn btn-default">
{% trans "Go" %}
</button>
</div>
<div class="col-md-5 col-sm-2 col-xs-4 text-right flip">
{% if has_before %}
<a href="?{% url_replace request "date" before|date:"Y-m" %}"
class="btn btn-default" data-save-scrollpos aria-label="{{ before|date:"F Y" }}">
<span class="fa fa-arrow-left" aria-hidden="true"></span>
<span class="hidden-sm hidden-xs">{{ before|date:"F Y" }}</span>
</a>
{% endif %}
{% if has_after %}
<a href="?{% url_replace request "date" after|date:"Y-m" %}"
class="btn btn-default" data-save-scrollpos aria-label="{{ after|date:"F Y" }}">
<span class="fa fa-arrow-right" aria-hidden="true"></span>
<span class="hidden-sm hidden-xs">{{ after|date:"F Y" }}</span>
</a>
{% endif %}
</div>
<div class="blank-after text-left flip">
{% include "pretixpresale/fragment_calendar_nav.html" with date=date request=request style="calendar" %}
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h2 class="panel-title">
<strong>
{% blocktrans trimmed with month=date|date:"F Y" %}
Events in {{ month }}
{% endblocktrans %}
</strong>
</h2>
</div>
</form>
{% include "pretixpresale/fragment_event_list_filter.html" with request=request %}
{% include "pretixpresale/fragment_calendar.html" with show_avail=request.organizer.settings.event_list_availability %}
{% if filter_form.fields %}
<div class="panel-subhead">
{% include "pretixpresale/fragment_event_list_filter.html" with request=request %}
</div>
{% endif %}
<div class="panel-body">
<nav aria-label="{% trans "calendar navigation" %}">
<ul class="row calendar-nav">
<li class="text-left flip">
{% if has_before %}
<a href="?{% url_replace request "date" before|date:"Y-m" %}"
class="btn btn-default" data-save-scrollpos aria-label="{{ before|date:"F Y" }}">
{% icon "arrow-left" %}
<span class="hidden-xs">{{ before|date:"F Y" }}</span>
</a>
{% endif %}
</li>
<li class="text-center">
<form class="form-inline" method="get" id="monthselform" action="{% eventurl request.organizer "presale:organizer.index" %}">
{% for f, v in request.GET.items %}
{% if f != "date" %}
<input type="hidden" name="{{ f }}" value="{{ v }}">
{% endif %}
{% endfor %}
<fieldset>
<legend class="sr-only">{% trans "Select a month to display" %}</legend>
<div>
<label for="calendar-input-date">{% trans "Month" %}</label>
</div>
<div class="input-group">
<select name="date" class="form-control" id="calendar-input-date">
{% for y in years %}
<optgroup label="{{ y }}">
{% for m in months %}
<option value="{{ y }}-{{ m|date:"m" }}" {% if m.month == date.month and y == date.year %}selected{% endif %}>{{ m|date:"F" }} {{ y }}</option>
{% endfor %}
</optgroup>
{% endfor %}
</select>
<span class="input-group-btn">
<button type="submit" class="btn btn-default" aria-label="{% trans "Show month" %}">
{% icon "chevron-right" %}
</button>
</span>
</div>
</fieldset>
</form>
</li>
<li class="text-right flip">
{% if has_after %}
<a href="?{% url_replace request "date" after|date:"Y-m" %}"
class="btn btn-default" data-save-scrollpos aria-label="{{ after|date:"F Y" }}">
<span class="hidden-xs">{{ after|date:"F Y" }}</span>
{% icon "arrow-right" %}
</a>
{% endif %}
</li>
</ul>
</nav>
{% include "pretixpresale/fragment_calendar.html" with show_avail=request.organizer.settings.event_list_availability %}
</div>
</div>
{% if multiple_timezones %}
<div class="alert alert-info">
{% blocktrans trimmed %}

View File

@@ -1,68 +1,102 @@
{% extends "pretixpresale/organizers/base.html" %}
{% load i18n %}
{% load icon %}
{% load rich_text %}
{% load eventurl %}
{% load urlreplace %}
{% block title %}{% trans "Event overview" %}{% endblock %}
{% block content %}
{% if organizer_homepage_text %}
<div>
<div class="blank-after">
{{ organizer_homepage_text | rich_text }}
</div>
{% endif %}
<h3>{{ date|date:"DATE_FORMAT" }}</h3>
<form class="form-inline" method="get" id="monthselform"
action="{% eventurl request.organizer "presale:organizer.index" %}">
{% for f, v in request.GET.items %}
{% if f != "date" %}
<input type="hidden" name="{{ f }}" value="{{ v }}">
{% endif %}
{% endfor %}
<div class="row">
<div class="col-md-5 col-sm-6 col-xs-12 text-left flip">
{% include "pretixpresale/fragment_calendar_nav.html" with date=date request=request style="day" %}
<div class="blank-after text-left flip">
{% include "pretixpresale/fragment_calendar_nav.html" with date=date request=request style="day" %}
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h2 class="panel-title">
<strong>
{% blocktrans trimmed with day=date|date:"DATE_FORMAT" %}
Events on {{ day }}
{% endblocktrans %}
</strong>
</h2>
</div>
{% if filter_form.fields %}
<div class="panel-subhead">
{% include "pretixpresale/fragment_event_list_filter.html" with request=request %}
</div>
<div class="col-md-2 col-sm-4 col-xs-8 text-center">
<input class="datepickerfield form-control" value="{{ date|date:"SHORT_DATE_FORMAT" }}" name="date">
<button type="submit" class="js-hidden btn btn-default">
{% trans "Go" %}
</button>
</div>
<div class="col-md-5 col-sm-2 col-xs-4 text-right flip">
{% endif %}
<div class="panel-body">
<nav aria-label="{% trans "calendar navigation" %}">
<ul class="row calendar-nav">
<li class="text-left flip">
{% if has_before %}
<a href="?{% url_replace request "date" before.date.isoformat %}"
class="btn btn-default" data-save-scrollpos aria-label="{{ before|date:"SHORT_DATE_FORMAT" }}">
{% icon "arrow-left" %}
<span class="hidden-xs">{{ before|date:"SHORT_DATE_FORMAT" }}</span>
</a>
{% endif %}
</li>
<li class="text-center">
<form class="form-inline" method="get" id="monthselform" action="{% eventurl request.organizer "presale:organizer.index" %}">
{% for f, v in request.GET.items %}
{% if f != "date" %}
<input type="hidden" name="{{ f }}" value="{{ v }}">
{% endif %}
{% endfor %}
<fieldset>
<legend class="sr-only">{% trans "Select a date to display" %}</legend>
<div>
<label for="calendar-input-date">{% trans "Date" %}</label>
</div>
<div class="input-group">
<input class="datepickerfield form-control" id="calendar-input-date" value="{{ date|date:"SHORT_DATE_FORMAT" }}" name="date">
<span class="input-group-btn">
<button type="submit" class="btn btn-default" aria-label="{% trans "Show date" %}">
{% icon "chevron-right" %}
</button>
</span>
</div>
</fieldset>
</form>
</li>
<li class="text-right flip">
{% if has_after %}
<a href="?{% url_replace request "date" after.date.isoformat %}"
class="btn btn-default" data-save-scrollpos aria-label="{{ after|date:"SHORT_DATE_FORMAT" }}">
<span class="hidden-xs">{{ after|date:"SHORT_DATE_FORMAT" }}</span>
{% icon "arrow-right" %}
</a>
{% endif %}
</li>
</ul>
</nav>
{% include "pretixpresale/fragment_day_calendar.html" with show_avail=request.organizer.settings.event_list_availability %}
<div class="row visible-xs">
{% if has_before %}
<div class="col-xs-6 text-left flip">
<a href="?{% url_replace request "date" before.date.isoformat %}"
class="btn btn-default" data-save-scrollpos aria-label="{{ before|date:"SHORT_DATE_FORMAT" }}">
class="btn btn-default">
<span class="fa fa-arrow-left" aria-hidden="true"></span>
<span class="hidden-sm hidden-xs">{{ before|date:"SHORT_DATE_FORMAT" }}</span>
<span class="hidden-xs">{{ before|date:"SHORT_DATE_FORMAT" }}</span>
</a>
</div>
{% endif %}
{% if has_after %}
<div class="col-xs-6 text-right flip{% if not has_before %} col-xs-offset-6{% endif %}">
<a href="?{% url_replace request "date" after.date.isoformat %}"
class="btn btn-default" data-save-scrollpos aria-label="{{ after|date:"SHORT_DATE_FORMAT" }}">
<span class="hidden-sm hidden-xs">{{ after|date:"SHORT_DATE_FORMAT" }}</span>
class="btn btn-default">
<span class="hidden-xs">{{ after|date:"SHORT_DATE_FORMAT" }}</span>
<span class="fa fa-arrow-right" aria-hidden="true"></span>
</a>
</div>
{% endif %}
</div>
</div>
</form>
{% include "pretixpresale/fragment_event_list_filter.html" with request=request %}
{% include "pretixpresale/fragment_day_calendar.html" with show_avail=request.organizer.settings.event_list_availability %}
<div class="col-sm-4 visible-xs text-center">
{% if has_before %}
<a href="?{% url_replace request "date" before.date.isoformat %}"
class="btn btn-default">
<span class="fa fa-arrow-left" aria-hidden="true"></span>
{{ before|date:"SHORT_DATE_FORMAT" }}
</a>
{% endif %}
{% if has_after %}
<a href="?{% url_replace request "date" after.date.isoformat %}"
class="btn btn-default">
{{ after|date:"SHORT_DATE_FORMAT" }}
<span class="fa fa-arrow-right" aria-hidden="true"></span>
</a>
{% endif %}
</div>
{% if multiple_timezones %}

View File

@@ -1,82 +1,117 @@
{% extends "pretixpresale/organizers/base.html" %}
{% load i18n %}
{% load icon %}
{% load rich_text %}
{% load eventurl %}
{% load urlreplace %}
{% block title %}{% trans "Event overview" %}{% endblock %}
{% block content %}
{% if organizer_homepage_text %}
<div>
<div class="blank-after">
{{ organizer_homepage_text | rich_text }}
</div>
{% endif %}
<h3>{{ date|date:"F Y" }}</h3>
<form class="form-inline" method="get" id="monthselform"
action="{% eventurl request.organizer "presale:organizer.index" %}">
{% for f, v in request.GET.items %}
{% if f != "date" %}
<input type="hidden" name="{{ f }}" value="{{ v }}">
{% endif %}
{% endfor %}
<div class="row">
<div class="col-md-4 col-sm-6 col-xs-12 text-left flip">
{% include "pretixpresale/fragment_calendar_nav.html" with date=date request=request style="week" %}
<div class="blank-after text-left flip">
{% include "pretixpresale/fragment_calendar_nav.html" with date=date request=request style="week" %}
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h2 class="panel-title">
<strong>
{% blocktrans trimmed with week=date|date:week_format week_day_from=date|date:short_month_day_format week_day_to=date|date:short_month_day_format %}
Events in {{ week }} ({{ week_day_from }} {{ week_day_to }})
{% endblocktrans %}
</strong>
</h2>
</div>
{% if filter_form.fields %}
<div class="panel-subhead">
{% include "pretixpresale/fragment_event_list_filter.html" with request=request %}
</div>
<div class="col-md-4 col-sm-4 col-xs-8 text-center">
<select name="date" class="form-control" aria-label="{% trans "Select week to show" %}">
{% for weeks_per_year in weeks %}
<optgroup label="{{ weeks_per_year.0.0.year }}">
{% for w in weeks_per_year %}
<option value="{{ w.0.isocalendar.0 }}-W{{ w.0.isocalendar.1 }}"
{% if w.0.isocalendar.0 == date.isocalendar.0 and w.0.isocalendar.1 == date.isocalendar.1 %}selected{% endif %}>
{{ w.0|date:week_format }}
({{ w.0|date:short_month_day_format }} {{ w.1|date:short_month_day_format }})
</option>
{% endfor %}
</optgroup>
{% endfor %}
</select>
<button type="submit" class="js-hidden btn btn-default">
{% trans "Go" %}
</button>
</div>
<div class="col-md-4 col-sm-2 col-xs-4 text-right flip">
{% endif %}
<div class="panel-body">
<nav aria-label="{% trans "calendar navigation" %}">
<ul class="row calendar-nav">
<li class="text-left flip">
{% if has_before %}
<a href="?{% url_replace request "date" before|date:"o-\WW" %}"
class="btn btn-default" data-save-scrollpos aria-label="{{ before|date:week_format }}">
{% icon "arrow-left" %}
<span class="hidden-xs">{{ before|date:week_format }}</span>
</a>
{% endif %}
</li>
<li class="text-center">
<form class="form-inline" method="get" id="monthselform" action="{% eventurl request.organizer "presale:organizer.index" %}">
{% for f, v in request.GET.items %}
{% if f != "date" %}
<input type="hidden" name="{{ f }}" value="{{ v }}">
{% endif %}
{% endfor %}
<fieldset>
<legend class="sr-only">{% trans "Select a week to display" %}</legend>
<div>
<label for="calendar-input-date">{% trans "Week" %}</label>
</div>
<div class="input-group">
<select name="date" class="form-control" id="calendar-input-date">
{% for weeks_per_year in weeks %}
<optgroup label="{{ weeks_per_year.0.0.year }}">
{% for w in weeks_per_year %}
<option value="{{ w.0.isocalendar.0 }}-W{{ w.0.isocalendar.1 }}"
{% if w.0.isocalendar.0 == date.isocalendar.0 and w.0.isocalendar.1 == date.isocalendar.1 %}selected{% endif %}>
{{ w.0|date:week_format }}
({{ w.0|date:short_month_day_format }} {{ w.1|date:short_month_day_format }})
</option>
{% endfor %}
</optgroup>
{% endfor %}
</select>
<span class="input-group-btn">
<button type="submit" class="btn btn-default" aria-label="{% trans "Show week" %}">
{% icon "chevron-right" %}
</button>
</span>
</div>
</fieldset>
</form>
</li>
<li class="text-right flip">
{% if has_after %}
<a href="?{% url_replace request "date" after|date:"o-\WW" %}"
class="btn btn-default" data-save-scrollpos aria-label="{{ after|date:week_format }}">
<span class="hidden-xs">{{ after|date:week_format }}</span>
{% icon "arrow-right" %}
</a>
{% endif %}
</li>
</ul>
</nav>
{% include "pretixpresale/fragment_week_calendar.html" with show_avail=request.organizer.settings.event_list_availability %}
<div class="row visible-sm visible-xs">
{% if has_before %}
<div class="col-xs-6 text-left flip">
<a href="?{% url_replace request "date" before|date:"o-\WW" %}"
class="btn btn-default" data-save-scrollpos aria-label="{{ before|date:week_format }}">
class="btn btn-default">
<span class="fa fa-arrow-left" aria-hidden="true"></span>
<span class="hidden-sm hidden-xs">{{ before|date:week_format }}</span>
{{ before|date:week_format }}
</a>
</div>
{% endif %}
{% if has_after %}
<div class="col-xs-6 text-right flip">
<a href="?{% url_replace request "date" after|date:"o-\WW" %}"
class="btn btn-default" data-save-scrollpos aria-label="{{ after|date:week_format }}">
<span class="hidden-sm hidden-xs">{{ after|date:week_format }}</span>
class="btn btn-default">
{{ after|date:week_format }}
<span class="fa fa-arrow-right" aria-hidden="true"></span>
</a>
</div>
{% endif %}
</div>
</div>
</form>
{% include "pretixpresale/fragment_event_list_filter.html" with request=request %}
{% include "pretixpresale/fragment_week_calendar.html" with show_avail=request.organizer.settings.event_list_availability %}
<div class="col-sm-12 visible-sm visible-xs text-center">
{% if has_before %}
<a href="?{% url_replace request "date" before|date:"o-\WW" %}"
class="btn btn-default">
<span class="fa fa-arrow-left" aria-hidden="true"></span>
{{ before|date:week_format }}
</a>
{% endif %}
{% if has_after %}
<a href="?{% url_replace request "date" after|date:"o-\WW" %}"
class="btn btn-default">
{{ after|date:week_format }}
<span class="fa fa-arrow-right" aria-hidden="true"></span>
</a>
{% endif %}
</div>
{% if multiple_timezones %}
<div class="alert alert-info">
{% blocktrans trimmed %}

View File

@@ -7,7 +7,7 @@
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">
{% icon "address-card-o" %} <b>{% trans "Delete address" %}</b>
{% icon "address-card-o" %} <strong>{% trans "Delete address" %}</strong>
</h3>
</div>
<div class="panel-body account-addresses">

View File

@@ -8,7 +8,7 @@
<div class="panel-heading">
<h3 class="panel-title">
{% icon "address-card-o" %}
<b>{% trans "Addresses" %}</b> ({{ page_obj.paginator.count }})
<strong>{% trans "Addresses" %}</strong> ({{ page_obj.paginator.count }})
</h3>
</div>
<div class="panel-body">

View File

@@ -6,19 +6,26 @@
{% block title %}{% trans "Account information" %}{% endblock %}
{% block content %}
<div class="row">
<div class="col-md-6 col-md-offset-3">
<h2>
{% blocktrans trimmed %}
Update your account information
{% endblocktrans %}
</h2>
<form action="" method="post">
<div class="col-xs-12">
<form action="" method="post" class="form-horizontal">
{% csrf_token %}
{% bootstrap_form form %}
<div class="form-group buttons">
<button type="submit" class="btn btn-primary btn-lg btn-block">
{% trans "Save" %}
</button>
<div class="panel panel-default">
<div class="panel-heading">
<h2 class="panel-title">
{% trans "Update your account information" %}
</h2>
</div>
<div class="panel-body">
{% bootstrap_form form layout="checkout" %}
</div>
</div>
<div class="row checkout-button-row">
<div class="col-md-4 col-md-offset-8">
<button class="btn btn-block btn-primary btn-lg" type="submit">
{% trans "Save" %}
</button>
</div>
<div class="clearfix"></div>
</div>
</form>
</div>

View File

@@ -7,48 +7,70 @@
{% block content %}
<div class="row">
<div class="col-md-6 col-md-offset-3">
<h2>
{% if request.organizer.settings.customer_accounts_native %}
<form action="" method="post" class="form-horizontal blank-after">
{% csrf_token %}
<div class="panel panel-primary">
<div class="panel-heading">
<h2 class="panel-title">
{% blocktrans trimmed with org=request.organizer.name %}
Sign in to your account at {{ org }}
{% endblocktrans %}
</h2>
</div>
<div class="panel-body">
{% bootstrap_form form layout="checkout" %}
<div class="row">
<div class="col-md-8 col-sm-6 hidden-xs">
<a class="btn btn-link btn-lg"
href="{% eventurl request.organizer "presale:organizer.customer.register" %}">
<small>
{% icon "address-book-o" %}
{% trans "Create account" %}
</small>
</a>
</div>
<div class="col-md-4 col-sm-6">
<button class="btn btn-block btn-primary btn-lg" type="submit">
{% icon "sign-in" %}
{% trans "Log in" %}
</button>
</div>
<div class="clearfix"></div>
</div>
<div class="row visible-xs">
<div class="col-xs-12 text-center"><br>
<a
href="{% eventurl request.organizer "presale:organizer.customer.register" %}">
{% icon "address-book-o" %}
{% trans "Create account" %}
</a>
</div>
</div>
</div>
</div>
</form>
{% else %}
<h2 class="blank-after">
{% blocktrans trimmed with org=request.organizer.name %}
Sign in to your account at {{ org }}
{% endblocktrans %}
</h2>
<form action="" method="post">
{% csrf_token %}
{% if request.organizer.settings.customer_accounts_native %}
{% bootstrap_form form %}
<div class="form-group buttons">
<button type="submit" class="btn btn-primary btn-lg btn-block">
{% icon "sign-in" %}
{% trans "Log in" %}
</button>
</div>
{% endif %}
</h2>
{% endif %}
{% if providers %}
<ul class="list-inline text-center blank-after">
{% for provider in providers %}
{% if provider.is_active %}
<li>
<a href="{% eventurl request.organizer "presale:organizer.customer.login" provider=provider.pk %}?{{ request.META.QUERY_STRING }}"
class="btn btn-primary btn-lg btn-block">
{{ provider.button_label }}
class="btn {% if request.organizer.settings.customer_accounts_native %}btn-default{% else %}btn-primary btn-lg btn-block{% endif %}">
{% icon "sign-in" %} {{ provider.button_label }}
</a>
{% endif %}
</li>
{% endfor %}
{% if request.organizer.settings.customer_accounts_native %}
<div class="row">
<div class="col-md-6">
<a class="btn btn-link btn-block"
href="{% eventurl request.organizer "presale:organizer.customer.register" %}">
{% icon "address-book-o" %}
{% trans "Create account" %}
</a>
</div>
<div class="col-md-6">
<a class="btn btn-link btn-block"
href="{% eventurl request.organizer "presale:organizer.customer.resetpw" %}">
{% trans "Reset password" %}
</a>
</div>
</div>
{% endif %}
</form>
</ul>
{% endif %}
</div>
</div>
<p>&nbsp;</p>

View File

@@ -13,7 +13,7 @@
{% else %}
{% icon "id-badge" %}
{% endif %}
<b>{% trans "Your membership" %}</b>
<strong>{% trans "Your membership" %}</strong>
{% if membership.testmode %}
<span class="h6">
{% textbubble "warning" %}

View File

@@ -9,7 +9,7 @@
<div class="panel-heading">
<h3 class="panel-title">
{% icon "id-badge" %}
<b>{% trans "Memberships" %}</b> ({{ page_obj.paginator.count }})
<strong>{% trans "Memberships" %}</strong> ({{ page_obj.paginator.count }})
</h3>
</div>
<div class="panel-body">

View File

@@ -10,7 +10,7 @@
<div class="panel-heading">
<h3 class="panel-title">
{% icon "shopping-cart" %}
<b>{% trans "Orders" %}</b> ({{ page_obj.paginator.count }})
<strong>{% trans "Orders" %}</strong> ({{ page_obj.paginator.count }})
</h3>
</div>
<div class="panel-body">

View File

@@ -7,18 +7,25 @@
{% block content %}
<div class="row">
<div class="col-md-6 col-md-offset-3">
<h2>
{% blocktrans trimmed %}
Set a new password for your account
{% endblocktrans %}
</h2>
<form action="" method="post">
<form action="" method="post" class="form-horizontal">
{% csrf_token %}
{% bootstrap_form form %}
<div class="form-group buttons">
<button type="submit" class="btn btn-primary btn-lg btn-block">
{% trans "Save" %}
</button>
<div class="panel panel-default">
<div class="panel-heading">
<h2 class="panel-title">
{% trans "Set a new password for your account" %}
</h2>
</div>
<div class="panel-body">
{% bootstrap_form form layout="checkout" %}
</div>
</div>
<div class="row checkout-button-row">
<div class="col-md-4 col-md-offset-8">
<button class="btn btn-block btn-primary btn-lg" type="submit">
{% trans "Save" %}
</button>
</div>
<div class="clearfix"></div>
</div>
</form>
</div>

View File

@@ -7,7 +7,7 @@
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">
{% icon "user" %} <b>{% trans "Delete profile" %}</b>
{% icon "user" %} <strong>{% trans "Delete profile" %}</strong>
</h3>
</div>
<div class="panel-body">

View File

@@ -8,7 +8,7 @@
<div class="panel-heading">
<h3 class="panel-title">
{% icon "users" %}
<b>{% trans "Attendee profiles" %}</b> ({{ page_obj.paginator.count }})
<strong>{% trans "Attendee profiles" %}</strong> ({{ page_obj.paginator.count }})
</h3>
</div>
<div class="panel-body">

View File

@@ -1,28 +1,54 @@
{% extends "pretixpresale/organizers/base.html" %}
{% load i18n %}
{% load icon %}
{% load eventurl %}
{% load urlreplace %}
{% load bootstrap3 %}
{% block title %}{% trans "Registration" %}{% endblock %}
{% block content %}
<div class="row">
<div class="col-md-6 col-md-offset-3">
<h2>
{% blocktrans trimmed with org=request.organizer.name %}
Create a new account at {{ org }}
{% endblocktrans %}
</h2>
<form action="" method="post">
<div class="col-xs-12">
<form action="" method="post" class="form-horizontal">
{% csrf_token %}
{% bootstrap_form form %}
<div class="form-group buttons">
<button type="submit" class="btn btn-primary btn-lg btn-block">
{% trans "Create account" %}
</button>
<div class="panel panel-default">
<div class="panel-heading">
<h2 class="panel-title">
{% blocktrans trimmed with org=request.organizer.name %}
Create a new account at {{ org }}
{% endblocktrans %}
</h2>
</div>
<div class="panel-body">
{% bootstrap_form form layout="checkout" %}
</div>
</div>
<div class="row checkout-button-row blank-after">
<div class="col-md-8 col-sm-6 hidden-xs">
<a class="btn btn-link btn-lg"
href="{% eventurl request.organizer "presale:organizer.customer.login" %}">
<small>
{% icon "sign-in" %}
{% trans "Log in to an existing account" %}
</small>
</a>
</div>
<div class="col-md-4 col-sm-6">
<button class="btn btn-block btn-primary btn-lg" type="submit">
{% icon "address-book-o" %}
{% trans "Create account" %}
</button>
</div>
<div class="clearfix"></div>
</div>
<div class="row visible-xs">
<div class="col-xs-12 text-center">
<a
href="{% eventurl request.organizer "presale:organizer.customer.login" %}">
{% icon "sign-in" %}
{% trans "Log in to an existing account" %}
</a>
</div>
</div>
<a class="btn btn-link btn-block" href="{% eventurl request.organizer "presale:organizer.customer.login" %}">
{% trans "Log in to an existing account" %}
</a>
</form>
</div>
</div>

View File

@@ -1,5 +1,6 @@
{% extends "pretixpresale/organizers/base.html" %}
{% load i18n %}
{% load icon %}
{% load eventurl %}
{% load urlreplace %}
{% load bootstrap3 %}
@@ -7,18 +8,44 @@
{% block content %}
<div class="row">
<div class="col-md-6 col-md-offset-3">
<h2>
{% blocktrans trimmed %}
Password reset
{% endblocktrans %}
</h2>
<form action="" method="post">
<form action="" method="post" class="form-horizontal">
{% csrf_token %}
{% bootstrap_form form %}
<div class="form-group buttons">
<button type="submit" class="btn btn-primary btn-lg btn-block">
{% trans "Request a new password" %}
</button>
<div class="panel panel-primary">
<div class="panel-heading">
<h2 class="panel-title">
{% trans "Request a new password" %}
</h2>
</div>
<div class="panel-body">
{% bootstrap_form form layout="checkout" %}
<div class="row">
<div class="col-sm-4 hidden-xs">
<a class="btn btn-link btn-lg"
href="{% eventurl request.organizer "presale:organizer.customer.login" %}">
<small>
{% icon "sign-in" %}
{% trans "Log in" %}
</small>
</a>
</div>
<div class="col-sm-8">
<button class="btn btn-block btn-primary btn-lg" type="submit">
{% trans "Request a new password" %}
</button>
</div>
<div class="clearfix"></div>
</div>
<div class="row visible-xs">
<div class="col-xs-12 text-center">
<a
href="{% eventurl request.organizer "presale:organizer.customer.register" %}">
{% icon "sign-in" %}
{% trans "Log in" %}
</a>
</div>
</div>
</div>
</div>
</form>
</div>

View File

@@ -7,18 +7,25 @@
{% block content %}
<div class="row">
<div class="col-md-6 col-md-offset-3">
<h2>
{% blocktrans trimmed %}
Set a new password for your account
{% endblocktrans %}
</h2>
<form action="" method="post">
<form action="" method="post" class="form-horizontal">
{% csrf_token %}
{% bootstrap_form form %}
<div class="form-group buttons">
<button type="submit" class="btn btn-primary btn-lg btn-block">
{% trans "Save" %}
</button>
<div class="panel panel-default">
<div class="panel-heading">
<h2 class="panel-title">
{% trans "Set a new password for your account" %}
</h2>
</div>
<div class="panel-body">
{% bootstrap_form form layout="checkout" %}
</div>
</div>
<div class="row checkout-button-row blank-after">
<div class="col-md-4 col-md-offset-8">
<button class="btn btn-block btn-primary btn-lg" type="submit">
{% trans "Save" %}
</button>
</div>
<div class="clearfix"></div>
</div>
</form>
</div>

View File

@@ -19,28 +19,24 @@
<meta property="og:url" content="{% abseventurl organizer "presale:organizer.index" %}"/>
{% endblock %}
{% block content %}
<div>
{% if organizer_homepage_text %}
{% if organizer_homepage_text %}
<div class="blank-after">
{{ organizer_homepage_text | rich_text }}
{% endif %}
</div>
<div id="monthselform">
<div class="row">
<div class="col-md-12">
{% include "pretixpresale/fragment_calendar_nav.html" with date=date request=request style="list" %}
</div>
</div>
{% endif %}
<div class="blank-after text-left flip">
{% include "pretixpresale/fragment_calendar_nav.html" with date=date request=request style="list" %}
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h2 class="panel-title">
<b>
<strong>
{% if "old" in request.GET %}
{% trans "Past events" %}
{% else %}
{% trans "Upcoming events" %}
{% endif %}
</b>
</strong>
</h2>
</div>
{% if filter_form.fields %}
@@ -69,6 +65,7 @@
<br>
<span class="text-muted" data-time="{{ e.date_from.isoformat }}" data-timezone="{{ e.tzname }}">
{% icon "clock-o" %}
<span class="sr-only">{% trans "Time of day" %}</span>
<time datetime="{{ e.date_from|date_fast:"H:i" }}">{{ e.date_from|date:"TIME_FORMAT" }}</time>
{% if e.settings.show_date_to and e.date_to and e.date_to.date == e.date_from.date %}
<span aria-hidden="true"></span><span class="sr-only">{% trans "until" context "timerange" %}</span>

View File

@@ -56,6 +56,7 @@ frame_wrapped_urls = [
re_path(r'^cart/remove$', pretix.presale.views.cart.CartRemove.as_view(), name='event.cart.remove'),
re_path(r'^cart/voucher$', pretix.presale.views.cart.CartApplyVoucher.as_view(), name='event.cart.voucher'),
re_path(r'^cart/clear$', pretix.presale.views.cart.CartClear.as_view(), name='event.cart.clear'),
re_path(r'^cart/extend$', pretix.presale.views.cart.CartExtendReservation.as_view(), name='event.cart.extend'),
re_path(r'^cart/answer/(?P<answer>[^/]+)/$',
pretix.presale.views.cart.AnswerDownload.as_view(),
name='event.cart.download.answer'),

View File

@@ -229,11 +229,13 @@ class CartMixin:
try:
first_expiry = min(p.expires for p in positions) if positions else now()
max_expiry_extend = min((p.max_extend for p in positions if p.max_extend), default=None)
total_seconds_left = max(first_expiry - now(), timedelta()).total_seconds()
minutes_left = int(total_seconds_left // 60)
seconds_left = int(total_seconds_left % 60)
except AttributeError:
first_expiry = None
max_expiry_extend = None
minutes_left = None
seconds_left = None
@@ -250,6 +252,7 @@ class CartMixin:
'minutes_left': minutes_left,
'seconds_left': seconds_left,
'first_expiry': first_expiry,
'max_expiry_extend': max_expiry_extend,
'is_ordered': bool(order),
'itemcount': sum(c.count for c in positions if not c.addon_to),
'current_selected_payments': [p for p in self.current_selected_payments(total) if p.get('multi_use_supported')]

View File

@@ -62,7 +62,7 @@ from pretix.base.models import (
)
from pretix.base.services.cart import (
CartError, add_items_to_cart, apply_voucher, clear_cart, error_messages,
remove_cart_position,
extend_cart_reservation, remove_cart_position,
)
from pretix.base.timemachine import time_machine_now
from pretix.base.views.tasks import AsyncAction
@@ -537,6 +537,26 @@ class CartClear(EventViewMixin, CartActionMixin, AsyncAction, View):
request.sales_channel.identifier, time_machine_now(default=None))
@method_decorator(allow_frame_if_namespaced, 'dispatch')
class CartExtendReservation(EventViewMixin, CartActionMixin, AsyncAction, View):
task = extend_cart_reservation
known_errortypes = ['CartError']
def _ajax_response_data(self, value):
if isinstance(value, dict):
return value
else:
return {}
def get_success_message(self, value):
if value['success'] > 0:
return _('Your cart timeout was extended.')
def post(self, request, *args, **kwargs):
return self.do(self.request.event.id, get_or_create_cart_id(self.request), translation.get_language(),
request.sales_channel.identifier, time_machine_now(default=None))
@method_decorator(allow_cors_if_namespaced, 'dispatch')
@method_decorator(allow_frame_if_namespaced, 'dispatch')
@method_decorator(iframe_entry_view_wrapper, 'dispatch')
@@ -547,7 +567,7 @@ class CartAdd(EventViewMixin, CartActionMixin, AsyncAction, View):
def get_success_message(self, value):
return _('The products have been successfully added to your cart.')
def _ajax_response_data(self):
def _ajax_response_data(self, value):
cart_id = get_or_create_cart_id(self.request)
return {
'cart_id': cart_id,

View File

@@ -122,7 +122,7 @@ class LoginView(RedirectBackMixin, FormView):
def get_context_data(self, **kwargs):
return super().get_context_data(
**kwargs,
providers=self.request.organizer.sso_providers.all()
providers=self.request.organizer.sso_providers.filter(is_active=True)
)
def get_form_kwargs(self):

View File

@@ -815,6 +815,7 @@ class EventIndex(EventViewMixin, EventListMixin, CartMixin, TemplateView):
se for se in context['subevent_list']
if not se.presale_has_ended and (se.best_availability_state is None or se.best_availability_state >= Quota.AVAILABILITY_RESERVED)
]
context['visible_events'] = len(context['subevent_list']) > 0
return context

View File

@@ -70,6 +70,7 @@ from pretix.helpers.formats.en.formats import (
SHORT_MONTH_DAY_FORMAT, WEEK_FORMAT,
)
from pretix.helpers.http import redirect_to_url
from pretix.helpers.i18n import parse_date_localized
from pretix.helpers.thumb import get_thumbnail
from pretix.multidomain.urlreverse import build_absolute_uri, eventreverse
from pretix.presale.forms.organizer import EventListFilterForm
@@ -927,10 +928,9 @@ class DayCalendarView(OrganizerViewMixin, EventListMixin, TemplateView):
def _set_date(self):
if 'date' in self.request.GET:
self.tz = self.request.organizer.timezone
try:
self.date = dateutil.parser.parse(self.request.GET.get('date')).date()
except ValueError:
self.date = now().astimezone(self.tz).date()
self.date = (
parse_date_localized(self.request.GET.get('date')) or now().astimezone(self.tz)
).date()
else:
self._set_date_to_next_event()

File diff suppressed because it is too large Load Diff

View File

@@ -4,8 +4,8 @@
"private": true,
"scripts": {},
"dependencies": {
"@babel/core": "^7.26.10",
"@babel/preset-env": "^7.26.9",
"@babel/core": "^7.27.1",
"@babel/preset-env": "^7.27.1",
"@rollup/plugin-babel": "^6.0.4",
"@rollup/plugin-node-resolve": "^16.0.1",
"vue": "^2.7.16",

View File

@@ -51,6 +51,13 @@ $(function () {
const required = 'required' in options && options.required && isRequired && visible;
dependent.closest(".form-group").toggle(visible).toggleClass('required', required);
dependent.prop("required", required);
const label = dependent.closest(".form-group").find("label");
const labelRequired = label.find(".label-required");
if (!required) {
labelRequired.remove();
} else if (!labelRequired.length) {
label.append('<i class="label-required">' + gettext('required') + '</i>')
}
}
for (var k in dependents) dependents[k].prop("disabled", false);
}).always(function() {
@@ -64,6 +71,7 @@ $(function () {
dependent.closest(".form-group").toggle(visible).toggleClass('required', required);
dependent.prop("required", required);
dependent.closest(".form-group").find("label .label-required").remove();
}
});
};

View File

@@ -5,74 +5,94 @@ var async_task_check_url = null;
var async_task_old_url = null;
var async_task_is_download = false;
var async_task_is_long = false;
var async_task_dont_redirect = false;
function async_task_check() {
var async_task_status_messages = {
long_task_started: gettext(
'Your request is currently being processed. Depending on the size of your event, this might take up to ' +
'a few minutes.'
),
long_task_pending: gettext(
'Your request has been queued on the server and will soon be ' +
'processed.'
),
short_task: gettext(
'Your request arrived on the server but we still wait for it to be ' +
'processed. If this takes longer than two minutes, please contact us or go ' +
'back in your browser and try again.'
)
};
function async_task_schedule_check(context, timeout) {
"use strict";
$.ajax(
{
'type': 'GET',
'url': async_task_check_url,
'success': async_task_check_callback,
'error': async_task_check_error,
'context': this,
'dataType': 'json'
async_task_timeout = window.setTimeout(function() {
$.ajax(
{
'type': 'GET',
'url': async_task_check_url,
'success': async_task_check_callback,
'error': async_task_check_error,
'context': context,
'dataType': 'json'
}
);
}, timeout);
}
function async_task_on_success(data) {
"use strict";
if ((async_task_is_download && data.success) || async_task_dont_redirect) {
waitingDialog.hide();
if (location.href.indexOf("async_id") !== -1) {
history.replaceState({}, "pretix", async_task_old_url);
}
);
}
if (!async_task_dont_redirect)
location.href = data.redirect;
$(this).trigger('pretix:async-task-success', data);
}
function async_task_check_callback(data, textStatus, jqXHR) {
"use strict";
if (data.ready && data.redirect) {
if (async_task_is_download && data.success) {
waitingDialog.hide();
if (location.href.indexOf("async_id") !== -1) {
history.replaceState({}, "pretix", async_task_old_url);
}
}
location.href = data.redirect;
async_task_on_success.call(this, data);
return;
} else if (typeof data.percentage === "number") {
$("#loadingmodal .progress").show();
$("#loadingmodal .progress .progress-bar").css("width", data.percentage + "%");
if (typeof data.steps === "object" && Array.isArray(data.steps)) {
var $steps = $("#loadingmodal .steps");
$steps.html("").show()
for (var step of data.steps) {
$steps.append(
$("<span>").addClass("fa fa-fw")
.toggleClass("fa-check text-success", step.done)
.toggleClass("fa-cog fa-spin text-muted", !step.done)
).append(
$("<span>").text(step.label)
).append(
$("<br>")
)
}
}
}
async_task_timeout = window.setTimeout(async_task_check, 250);
if (typeof data.percentage === "number") {
waitingDialog.setProgress(data.percentage);
}
if (typeof data.steps === "object" && Array.isArray(data.steps)) {
waitingDialog.setSteps(data.steps);
}
async_task_schedule_check(this, 250);
async_task_update_status(data);
}
function async_task_update_status(data) {
if (async_task_is_long) {
if (data.started) {
$("#loadingmodal p.status").text(gettext(
'Your request is currently being processed. Depending on the size of your event, this might take up to ' +
'a few minutes.'
));
waitingDialog.setStatus(async_task_status_messages.long_task_started);
} else {
$("#loadingmodal p.status").text(gettext(
'Your request has been queued on the server and will soon be ' +
'processed.'
));
waitingDialog.setStatus(async_task_status_messages.long_task_pending);
}
} else {
$("#loadingmodal p.status").text(gettext(
'Your request arrived on the server but we still wait for it to be ' +
'processed. If this takes longer than two minutes, please contact us or go ' +
'back in your browser and try again.'
));
waitingDialog.setStatus(async_task_status_messages.short_task);
}
}
function async_task_replace_page(target, new_html) {
"use strict";
waitingDialog.hide();
$(target).html(new_html);
setup_basics($(target));
form_handlers($(target));
setup_collapsible_details($(target));
window.setTimeout(function () { $(window).scrollTop(0) }, 200)
$(document).trigger("pretix:bind-forms");
}
function async_task_check_error(jqXHR, textStatus, errorThrown) {
"use strict";
var respdom = $(jqXHR.responseText);
@@ -80,16 +100,10 @@ function async_task_check_error(jqXHR, textStatus, errorThrown) {
if (respdom.filter('form') && (respdom.filter('.has-error') || respdom.filter('.alert-danger'))) {
// This is a failed form validation, let's just use it
$("body").data('ajaxing', false);
waitingDialog.hide();
$("body").html(jqXHR.responseText.substring(
async_task_replace_page("body", jqXHR.responseText.substring(
jqXHR.responseText.indexOf("<body"),
jqXHR.responseText.indexOf("</body")
));
setup_basics($("body"));
form_handlers($("body"));
setup_collapsible_details($("body"));
window.setTimeout(function () { $(window).scrollTop(0) }, 200)
$(document).trigger("pretix:bind-forms");
} else if (c.length > 0) {
// This is some kind of 500/404/403 page, show it in an overlay
$("body").data('ajaxing', false);
@@ -105,9 +119,9 @@ function async_task_check_error(jqXHR, textStatus, errorThrown) {
alert(gettext('An error of type {code} occurred.').replace(/\{code\}/, jqXHR.status));
} else {
// 500 can be an application error or overload in some cases :(
$("#loadingmodal p.status").text(gettext('We currently cannot reach the server, but we keep trying.' +
' Last error code: {code}').replace(/\{code\}/, jqXHR.status));
async_task_timeout = window.setTimeout(async_task_check, 5000);
waitingDialog.setStatus(gettext('We currently cannot reach the server, but we keep trying.' +
' Last error code: {code}').replace(/\{code\}/, jqXHR.status));
async_task_schedule_check(this, 5000);
}
}
}
@@ -116,38 +130,15 @@ function async_task_callback(data, jqXHR, status) {
"use strict";
$("body").data('ajaxing', false);
if (data.redirect) {
if (async_task_is_download && data.success) {
waitingDialog.hide();
if (location.href.indexOf("async_id") !== -1) {
history.replaceState({}, "pretix", async_task_old_url);
}
}
location.href = data.redirect;
async_task_on_success.call(this, data);
return;
}
async_task_id = data.async_id;
async_task_check_url = data.check_url;
async_task_timeout = window.setTimeout(async_task_check, 100);
async_task_schedule_check(this, 100);
async_task_update_status(data);
if (async_task_is_long) {
if (data.started) {
$("#loadingmodal p.status").text(gettext(
'Your request is currently being processed. Depending on the size of your event, this might take up to ' +
'a few minutes.'
));
} else {
$("#loadingmodal p.status").text(gettext(
'Your request has been queued on the server and will soon be ' +
'processed.'
));
}
} else {
$("#loadingmodal p.status").text(gettext(
'Your request arrived on the server but we still wait for it to be ' +
'processed. If this takes longer than two minutes, please contact us or go ' +
'back in your browser and try again.'
));
}
if (location.href.indexOf("async_id") === -1) {
history.pushState({}, "Waiting", async_task_check_url.replace(/ajax=1/, ''));
}
@@ -156,48 +147,34 @@ function async_task_callback(data, jqXHR, status) {
function async_task_error(jqXHR, textStatus, errorThrown) {
"use strict";
$("body").data('ajaxing', false);
waitingDialog.hide();
if (textStatus === "timeout") {
alert(gettext("The request took too long. Please try again."));
waitingDialog.hide();
} else if (jqXHR.responseText.indexOf('<html') > 0) {
var respdom = $(jqXHR.responseText);
var c = respdom.filter('.container');
if (respdom.filter('form') && (respdom.filter('.has-error') || respdom.filter('.alert-danger'))) {
// This is a failed form validation, let's just use it
waitingDialog.hide();
if (respdom.filter('#page-wrapper') && $('#page-wrapper').length) {
$("#page-wrapper").html(respdom.find("#page-wrapper").html());
setup_basics($("#page-wrapper"));
form_handlers($("#page-wrapper"));
setup_collapsible_details($("#page-wrapper"));
$(document).trigger("pretix:bind-forms");
window.setTimeout(function () { $(window).scrollTop(0) }, 200)
async_task_replace_page("#page-wrapper", respdom.find("#page-wrapper").html());
} else {
$("body").html(jqXHR.responseText.substring(
async_task_replace_page("body", jqXHR.responseText.substring(
jqXHR.responseText.indexOf("<body"),
jqXHR.responseText.indexOf("</body")
));
setup_basics($("body"));
form_handlers($("body"));
setup_collapsible_details($("body"));
$(document).trigger("pretix:bind-forms");
window.setTimeout(function () { $(window).scrollTop(0) }, 200)
}
} else if (c.length > 0) {
waitingDialog.hide();
// This is some kind of 500/404/403 page, show it in an overlay
ajaxErrDialog.show(c.first().html());
} else {
waitingDialog.hide();
alert(gettext('An error of type {code} occurred.').replace(/\{code\}/, jqXHR.status));
}
} else {
if (jqXHR.status >= 400 && jqXHR.status < 500) {
waitingDialog.hide();
alert(gettext('An error of type {code} occurred.').replace(/\{code\}/, jqXHR.status));
} else {
waitingDialog.hide();
alert(gettext('We currently cannot reach the server. Please try again. ' +
'Error code: {code}').replace(/\{code\}/, jqXHR.status));
}
@@ -221,24 +198,19 @@ $(function () {
}
async_task_id = null;
async_task_is_download = $(this).is("[data-asynctask-download]");
async_task_dont_redirect = $(this).is("[data-asynctask-no-redirect]");
async_task_is_long = $(this).is("[data-asynctask-long]");
async_task_old_url = location.href;
$("body").data('ajaxing', true);
if ($(this).is("[data-asynctask-headline]")) {
waitingDialog.show($(this).attr("data-asynctask-headline"));
} else {
waitingDialog.show(gettext('We are processing your request …'));
}
if ($(this).is("[data-asynctask-text]")) {
$("#loadingmodal p.text").text($(this).attr("data-asynctask-text")).show();
} else {
$("#loadingmodal p.text").hide();
}
$("#loadingmodal p.status").text(gettext(
'We are currently sending your request to the server. If this takes longer ' +
'than one minute, please check your internet connection and then reload ' +
'this page and try again.'
));
waitingDialog.show(
$(this).attr("data-asynctask-headline") || gettext('We are processing your request …'),
$(this).attr("data-asynctask-text") || '',
gettext(
'We are currently sending your request to the server. If this takes longer ' +
'than one minute, please check your internet connection and then reload ' +
'this page and try again.'
)
);
var action = this.action;
var formData = new FormData(this);
@@ -275,34 +247,72 @@ $(function () {
}, 10);
}
}, false);
$("#ajaxerr").on("click", ".ajaxerr-close", ajaxErrDialog.hide);
});
var waitingDialog = {
show: function (message) {
"use strict";
$("#loadingmodal h3").html(message);
$("#loadingmodal .progress").hide();
$("#loadingmodal .steps").hide();
$("body").addClass("loading");
$("#loadingmodal").removeAttr("hidden");
},
hide: function () {
"use strict";
$("body").removeClass("loading");
$("#loadingmodal").attr("hidden", true);
function AsyncStatusDialog(options) {
ModalDialog.call(this, Object.assign({
content: [
this.statusEl = EL('p', {}),
this.progressEl = EL('div', {class: 'progress'}, EL('div', {class:'progress-bar progress-bar-success', hidden: ''})),
this.stepsEl = EL('div', {class: 'steps', hidden: ''}, ''),
]
}, options));
}
AsyncStatusDialog.prototype = Object.create(ModalDialog.prototype);
AsyncStatusDialog.prototype.show = function (title, text, status) {
ModalDialog.prototype.show.call(this);
this.setTitle(title);
this.setDescription(text);
this.setStatus(status || gettext('If this takes longer than a few minutes, please contact us.'));
this.setProgress(null);
this.setSteps(null);
}
AsyncStatusDialog.prototype.setStatus = function (text) {
this.statusEl.innerText = text;
}
AsyncStatusDialog.prototype.setProgress = function (percent) {
$(this.progressEl).toggle(typeof percent === 'number').find('.progress-bar').css('width', percent + '%');
}
AsyncStatusDialog.prototype.setSteps = function (steps) {
var $steps = $(this.stepsEl);
if (typeof steps === "object" && Array.isArray(steps)) {
$steps.html("").show();
for (var step of steps) {
$steps.append(
$("<span>").addClass("fa fa-fw")
.toggleClass("fa-check text-success", step.done)
.toggleClass("fa-cog fa-spin text-muted", !step.done)
).append(
$("<span>").text(step.label)
).append(
$("<br>")
)
}
} else {
$steps.html("").hide();
}
};
}
var waitingDialog;
$(function() {
waitingDialog = new AsyncStatusDialog({
icon: 'cog', rotatingIcon: true,
});
});
var ajaxErrDialog = {
show: function (c) {
"use strict";
$("#ajaxerr").html(c);
$("#ajaxerr").html(c).show();
$("#ajaxerr .links").html("<a class='btn btn-default ajaxerr-close'>"
+ gettext("Close message") + "</a>");
$("body").addClass("ajaxerr");
+ gettext("Close message") + "</a>");
ModalDialog.updateBodyClass();
},
hide: function () {
"use strict";
$("body").removeClass("ajaxerr");
$("#ajaxerr").hide();
ModalDialog.updateBodyClass();
}
};

View File

@@ -2,39 +2,56 @@
setup_collapsible_details = function (el) {
el.find('details.sneak-peek:not([open])').each(function() {
this.open = true;
var $elements = $("> :not(summary)", this).show().filter(':not(.sneak-peek-trigger)');
var container = this;
if (Array.prototype.reduce.call($elements, function (h, e) {
return h + $(e).outerHeight();
}, 0) < 200) {
$(".sneak-peek-trigger", this).remove();
$(container).removeClass('sneak-peek');
container.style.removeProperty('height');
el.find('.sneak-peek-trigger').each(function() {
var trigger = this;
var button = this.querySelector('button');
var content = document.getElementById(button.getAttribute('aria-controls'));
if (content.scrollHeight < 200) {
trigger.remove();
content.classList.remove('sneak-peek-content');
return;
}
content.setAttribute('aria-hidden', 'true');
button.setAttribute('aria-expanded', 'false');
button.addEventListener('click', function (e) {
button.setAttribute('aria-expanded', 'true');
content.setAttribute('aria-hidden', 'false');
$elements.attr('aria-hidden', 'true');
var trigger = $('summary, .sneak-peek-trigger button', container);
function onclick(e) {
e.preventDefault();
container.addEventListener('transitionend', function() {
$(container).removeClass('sneak-peek');
container.style.removeProperty('height');
content.addEventListener('transitionend', function() {
content.classList.remove('sneak-peek-content');
content.style.removeProperty('height');
// we need to keep the trigger/button in the DOM to not irritate screenreaders toggling visibility
trigger.classList.add('sr-only');
}, {once: true});
container.style.height = container.scrollHeight + 'px';
$('.sneak-peek-trigger', container).fadeOut(function() {
$(this).remove();
});
$elements.removeAttr('aria-hidden');
content.style.height = content.scrollHeight + 'px';
trigger.off('click', onclick);
button.addEventListener('click', function (e) {
// this will be called by screenreader users if they kept focus on the button after expanding
// we need to keep the trigger/button in the DOM to not irritate screenreaders toggling visibility
var expanded = button.getAttribute('aria-expanded') == 'true';
button.setAttribute('aria-expanded', !expanded);
content.setAttribute('aria-hidden', expanded);
});
button.addEventListener('blur', function (e) {
// if content is visible and the user leaves the button, we can safely remove the trigger/button
if (button.getAttribute('aria-expanded') == 'true') {
trigger.remove();
}
});
}, { once: true });
var container = this.closest('details.sneak-peek-container');
if (container) {
function removeSneekPeakWhenClosed(e) {
if (e.newState == "closed") {
container.removeEventListener("toggle", removeSneekPeakWhenClosed);
trigger.remove();
content.removeAttribute('aria-hidden');
content.classList.remove('sneak-peek-content');
}
}
container.addEventListener("toggle", removeSneekPeakWhenClosed);
}
trigger.on('click', onclick);
});
var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]';
@@ -43,10 +60,6 @@ setup_collapsible_details = function (el) {
return true;
}
var $details = $(this).closest("details");
if ($details.hasClass('sneak-peek')) {
// if sneak-peek is active, needs to be handled differently
return true;
}
var isOpen = $details.prop("open");
var $detailsNotSummary = $details.children(':not(summary)');
if ($detailsNotSummary.is(':animated')) {
@@ -70,11 +83,6 @@ setup_collapsible_details = function (el) {
if (32 == event.keyCode || (13 == event.keyCode && !isOpera)) {
// Space or Enter is pressed — trigger the `click` event on the `summary` element
// Opera already seems to trigger the `click` event when Enter is pressed
var $details = $(this).closest("details");
if ($details.hasClass('sneak-peek')) {
// if sneak-peek is active, needs to be handled differently
return true;
}
event.preventDefault();
$(this).click();
}

View File

@@ -0,0 +1,76 @@
/*global $,gettext,ngettext */
function EL(tagName, attrs) {
var el = document.createElement(tagName);
if (attrs) for(var key in attrs)
if (key === 'style' && typeof attrs[key] === 'object') Object.assign(el.style, attrs[key]);
else if (key === 'innerHTML') el.innerHTML = attrs[key];
else if (key === 'appendTo' && (attrs.appendTo instanceof HTMLElement || attrs.appendTo instanceof ShadowRoot)) attrs.appendTo.append(el);
else if (key === 'prependTo' && (attrs.prependTo instanceof HTMLElement || attrs.prependTo instanceof ShadowRoot)) attrs.prependTo.prepend(el);
else if (key === 'insertBefore' && attrs.insertBefore instanceof HTMLElement) attrs.insertBefore.before(el);
else if (key === 'insertAfter' && attrs.insertAfter instanceof HTMLElement) attrs.insertAfter.after(el);
else if (key.startsWith("on")) el.addEventListener(key.substring(2), attrs[key], false);
else if (key.startsWith(":")) el[key.substring(1)] = attrs[key];
else if (key === 'checked' && 'checked' in el) el.checked = attrs.checked;
else if (key === 'selected' && 'selected' in el) el.selected = attrs.selected;
else if (key === 'multiple' && 'multiple' in el) el.multiple = attrs.multiple;
else el.setAttribute(key, attrs[key]);
if (arguments[2] instanceof Array)
var args = arguments[2], i = 0;
else
var args = arguments, i = 2;
for(;i<args.length;i++){
if (args[i] instanceof HTMLElement) el.appendChild(args[i]);
else if (args[i]) el.appendChild(document.createTextNode(""+args[i]));
}
return el;
}
function ModalDialog(options) {
this.id = 'modal-dlg-' + (++ModalDialog._next_dialog_id);
this.options = options;
this.dialogEl = EL('dialog', {class: 'modal-card', id: this.id,
'aria-live': 'polite', 'aria-labelledby': this.id + '-title', 'aria-describedby': this.id + '-desc',
appendTo: document.body, onclose: this._onClose.bind(this)},
(options.icon)
? EL('div', {class: 'modal-card-icon'},
EL('i', {'aria-hidden': 'true', class: 'fa fa-' + options.icon + ' ' + (options.rotatingIcon ? 'big-rotating-icon' : 'big-icon')}))
: undefined,
EL('div', {class: 'modal-card-content'},
this.titleEl = EL('h3', {id: this.id + '-title'}, options.title || ''),
this.descEl = EL('p', {id: this.id + '-desc'}, options.description || ''),
this.contentEl = EL('div', {}, options.content || '')));
}
ModalDialog._next_dialog_id = 1;
ModalDialog.updateBodyClass = function() {
if ($("dialog[open], .modal-wrapper:not([hidden])").length)
$(document.body).addClass('has-modal-dialog');
else
$(document.body).removeClass('has-modal-dialog');
}
ModalDialog.prototype.show = function() {
this.dialogEl.showModal();
ModalDialog.updateBodyClass();
}
ModalDialog.prototype.hide = function() {
this.dialogEl.close();
}
ModalDialog.prototype.isOpen = function() {
return this.dialogEl.open;
}
ModalDialog.prototype._onClose = function() {
if (this.options.removeOnClose) this.dialogEl.remove();
ModalDialog.updateBodyClass();
}
ModalDialog.prototype.setTitle = function(text) {
this.titleEl.innerText = text;
}
ModalDialog.prototype.setDescription = function(text) {
this.descEl.innerText = text;
this.descEl.style.display = text ? '' : 'none';
}
ModalDialog.prototype.setContent = function(text) {
this.contentEl.innerText = text;
}

View File

@@ -227,6 +227,10 @@ svg.svg-icon {
top: 2px;
}
.text-muted path {
fill: $text-muted;
}
.link-muted a, a.link-muted {
color: $text-muted;
}

View File

@@ -0,0 +1,102 @@
body.has-modal-dialog .container, body.has-modal-dialog #wrapper {
-webkit-filter: blur(2px);
-moz-filter: blur(2px);
-ms-filter: blur(2px);
-o-filter: blur(2px);
filter: blur(2px);
}
.big-rotating-icon {
-webkit-animation: fa-spin 8s infinite linear;
animation: fa-spin 8s infinite linear;
font-size: 120px;
color: $brand-primary;
}
dialog.modal-card::backdrop {
background: rgba(255, 255, 255, .7);
}
.modal-wrapper {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background: rgba(255, 255, 255, .7);
z-index: 900000;
padding: 10px;
}
.modal-card {
margin: 50px auto 0;
width: 90%;
max-width: 600px;
max-height: calc(100vh - 100px);
overflow-y: auto;
background: white;
border-radius: $border-radius-large;
box-shadow: 0 7px 14px 0 rgba(78, 50, 92, 0.1),0 3px 6px 0 rgba(0,0,0,.07);
padding: 20px;
min-height: 160px;
border: 0;
.modal-card-icon {
float: left;
width: 150px;
text-align: center;
.big-icon {
margin-top: 10px;
font-size: 100px;
color: $brand-primary;
}
}
.modal-card-content {
margin-left: 160px;
text-align: left;
h3 {
margin-top: 0;
}
}
}
#cookie-consent-modal {
background: rgba(255, 255, 255, .5);
.modal-card-content {
margin-left: 0;
}
details {
& > summary {
list-style: none;
}
& > summary::-webkit-details-marker,
& > summary::marker {
display: none;
}
margin-bottom: 10px;
}
}
@media (max-width: 700px) {
.modal-card {
margin: 25px auto 0;
max-height: calc(100vh - 50px - 20px);
.modal-card-icon {
float: none;
width: 100%;
}
.modal-card-content {
text-align: center;
margin-left: 0;
margin-right: 0;
margin-top: 10px;
}
}
}
#ajaxerr {
background: rgba(236, 236, 236, .9);
.big-icon {
margin-top: 50px;
font-size: 200px;
color: $brand-primary;
}
}

View File

@@ -4,6 +4,26 @@ $(document).on("pretix:bind-forms", function () {
function cleanup(l) {
return $.trim(l.replace(/\n/g, ", "));
}
function combine($sel) {
var parts = [
$sel.filter("[name*=street]").val(),
$sel.filter("[name*=zipcode]").val(),
$sel.filter("[name*=city]").val(),
$sel.filter("[name*=state]").val(),
$sel.filter("[name*=country]").find("option:selected").text(),
$sel.filter("[name*=location]").val(),
]
var res = "";
for (var val of parts) {
if (val) {
if (res) {
res += ", "
}
res += val
}
}
return cleanup(res)
}
$(".geodata-section").each(function () {
// Geocoding
// detach notifications and append them to first label (should be from location)
@@ -13,8 +33,26 @@ $(document).on("pretix:bind-forms", function () {
var lat;
var lon;
var $updateButton = $("[data-action=update]", this);
var $location = $("textarea[lang=en], input[lang=en]", this).first();
if (!$location.length) $location = $("textarea, input[type=text]", this).first();
var $location;
// The .geodata-section is expected to include either...
// ... an English "location" field
if ($("textarea[lang=en], input[lang=en]", this).length) {
$location = $("textarea[lang=en], input[lang=en], select", this).not("[name*=geo_]");
}
// ... a "location" field in any other language
if (!$location || !$location.length) {
var lang = $("textarea, input[type=text]", this).not("[name*=geo_]").first().attr("lang");
if (lang) {
$location = $("textarea[lang=" + lang + "], input[lang=" + lang + "], select", this);
}
}
// ... or a set of fields like a full address form
if (!$location || !$location.length) {
$location = $("textarea, input, select", this).not("[name*=geo_]");
}
if (!$lat.length || !$lon.length || !$location.length) {
return;
@@ -23,7 +61,7 @@ $(document).on("pretix:bind-forms", function () {
var debounceLoad, debounceLatLonChange, delayUpdateDismissal;
var touched = $lat.val() !== "";
var xhr;
var lastLocation = cleanup($location.val());
var lastLocation = combine($location);
function load() {
window.clearTimeout(debounceLoad);
@@ -32,7 +70,7 @@ $(document).on("pretix:bind-forms", function () {
xhr = null;
}
var q = cleanup($location.val());
var q = combine($location);
if (q === "" || q === lastLocation) return;
lastLocation = q;

View File

@@ -51,32 +51,6 @@ function formatPrice(price, currency, locale) {
}
}
var waitingDialog = {
show: function (message) {
"use strict";
$("#loadingmodal").find("h1").html(message);
$("body").addClass("loading");
},
hide: function () {
"use strict";
$("body").removeClass("loading");
}
};
var ajaxErrDialog = {
show: function (c) {
"use strict";
$("#ajaxerr").html(c);
$("#ajaxerr .links").html("<a class='btn btn-default ajaxerr-close'>"
+ gettext("Close message") + "</a>");
$("body").addClass("ajaxerr");
},
hide: function () {
"use strict";
$("body").removeClass("ajaxerr");
}
};
var apiGET = function (url, callback) {
$.getJSON(url, function (data) {
callback(data);

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