Compare commits

..
Author SHA1 Message Date
Richard Schreiber eb61bcdd4e Fix email preview curly brackets mismatch 2024-05-29 16:11:05 +02:00
Raphael Michel 1566f54764 VAT ID validation: Fix crash with invalid Norwegian IDs (PRETIXEU-A3J) 2024-05-29 09:31:58 +02:00
Richard SchreiberandGitHub 9d380557e1 SEO improvements - add h1.sr-only if only header-image is used
* add hidden h1 with event-title if header-image only

* add event-title to alt-attribute of header-image

* add hidden setting for google_site_verification
2024-05-28 09:18:15 +02:00
Martin GrossandGitHub 5758e0dd68 PPv2 APM: Create referenced PPObjects for APM Orders; enable webhooks to capture them (#3958) 2024-05-27 13:45:37 +02:00
Martin Gross b4629e24a5 Downgrade requests to 2.31.* again while waiting for 2.33.3 release 2024-05-27 12:11:40 +02:00
Raphael Michel 27f5121211 Bump version to 2024.6.0.dev0 2024-05-24 14:11:21 +02:00
Raphael Michel a5007e4bd6 Bump version to 2024.5.0. 2024-05-24 14:10:29 +02:00
Richard SchreiberandGitHub fb3046210b Harden timing when getting order with secret check (#4177) 2024-05-24 14:09:18 +02:00
Raphael MichelandRaphael Michel 37908bd042 Translations: Update German (informal) (de_Informal)
Currently translated at 100.0% (5634 of 5634 strings)

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

powered by weblate
2024-05-24 11:04:49 +02:00
Raphael MichelandRaphael Michel 74bcbe8f07 Translations: Update German
Currently translated at 100.0% (5634 of 5634 strings)

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

powered by weblate
2024-05-24 11:04:49 +02:00
Raphael Michel 29f378c58b Update wordlists 2024-05-24 10:56:10 +02:00
Raphael Michel 9b537aeb5c Update po files
[CI skip]

Signed-off-by: Raphael Michel <michel@rami.io>
2024-05-24 10:47:49 +02:00
Raphael Michel 4b5cd35a0e Add a "the" 2024-05-24 10:47:49 +02:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
e0675233d5 Update protobuf requirement from ==5.26.* to ==5.27.* (#4174)
Updates the requirements on [protobuf](https://github.com/protocolbuffers/protobuf) to permit the latest version.
- [Release notes](https://github.com/protocolbuffers/protobuf/releases)
- [Changelog](https://github.com/protocolbuffers/protobuf/blob/main/protobuf_release.bzl)
- [Commits](https://github.com/protocolbuffers/protobuf/compare/v5.26.0-rc1...v5.27.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-24 10:47:32 +02:00
Raphael Michel e9726a5227 Update po files
[CI skip]

Signed-off-by: Raphael Michel <michel@rami.io>
2024-05-24 10:10:01 +02:00
78b65d0757 Document exhibitor_tags field in API docs (#4172)
* Document exhibitor_tags field in API

* Update doc/plugins/exhibitors.rst

---------

Co-authored-by: Raphael Michel <michel@rami.io>
2024-05-24 10:00:44 +02:00
Serhii HorichenkoandRaphael Michel ef620ceb37 Translations: Update Ukrainian
Currently translated at 63.8% (3587 of 5621 strings)

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

powered by weblate
2024-05-24 09:50:45 +02:00
Charlie LundbergandRaphael Michel 8575a5f1cd Translations: Update Swedish
Currently translated at 19.0% (1070 of 5621 strings)

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

powered by weblate
2024-05-24 09:50:45 +02:00
Sinan SarıçınarandRaphael Michel 5762ffc035 Translations: Update Turkish
Currently translated at 44.3% (2494 of 5621 strings)

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

powered by weblate
2024-05-24 09:50:45 +02:00
Raphael MichelandRaphael Michel 79286bb051 Translations: Update French
Currently translated at 96.4% (5424 of 5621 strings)

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

powered by weblate
2024-05-24 09:50:45 +02:00
MiraandGitHub 05a2f411db Improve order secret handling (#4139)
- use hmac.compare_digest for all secret comparisons
- use salted_hmac with sha256 instead of plain sha1 for hashed secrets
- move secret handling into helper functions
2024-05-23 14:30:16 +02:00
Raphael MichelandGitHub e93e5c047c Waiting list: Fix pathological performance on large series with seating (#4169) 2024-05-23 11:51:48 +02:00
Raphael MichelandGitHub 2619a658c9 Widget: Allow passing more invoice data fields (#4162) 2024-05-23 11:19:59 +02:00
Raphael MichelandGitHub 808775c76b Widget: Do not open seating plan when pressing return in input field (#4163) 2024-05-23 11:18:09 +02:00
Raphael MichelandGitHub 9f297fbd25 Widget: Fix data-invoice-address-country being overridden by GeoIP (#4168) 2024-05-23 11:17:54 +02:00
Serhii HorichenkoandRaphael Michel d882da0adb Translations: Update Ukrainian
Currently translated at 63.6% (3577 of 5621 strings)

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

powered by weblate
2024-05-23 11:17:02 +02:00
Serhii HorichenkoandRaphael Michel 73bd4a746e Translations: Update Ukrainian
Currently translated at 98.2% (225 of 229 strings)

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

powered by weblate
2024-05-23 11:17:02 +02:00
Serhii HorichenkoandRaphael Michel bc5d0763f3 Translations: Update Ukrainian
Currently translated at 63.6% (3576 of 5621 strings)

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

powered by weblate
2024-05-23 11:17:02 +02:00
Charlie LundbergandRaphael Michel ff084f04b1 Translations: Update Swedish
Currently translated at 19.0% (1069 of 5621 strings)

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

powered by weblate
2024-05-23 11:17:02 +02:00
Richard SchreiberandGitHub 71af40a08b Simplify merging rotated background PDFs (#4166)
* Simplify merging rotated background PDFs

* fix code style issues
2024-05-23 08:55:51 +02:00
ef60093bae Update pypdf requirement from ==3.9.* to ==4.2.* (#4159)
* Change PDF merging for compatibility with pypdf 4

* Update pypdf requirement from ==3.9.* to ==4.2.*

* fix pypdf API-changes

* fix missing removal of deepcopy

* fix rotated PDF-backgrounds

---------

Co-authored-by: Richard Schreiber <schreiber@rami.io>
2024-05-22 14:56:21 +02:00
MiraandGitHub 49c4cc639f Fix time machine permission via pretix_event_access sessions for staff users (#4160) 2024-05-22 13:13:50 +02:00
Charlie LundbergandRaphael Michel e2800019f6 Translations: Update Swedish
Currently translated at 86.0% (197 of 229 strings)

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

powered by weblate
2024-05-22 09:15:52 +02:00
Charlie LundbergandRaphael Michel c44ea8aa81 Translations: Update Swedish
Currently translated at 18.2% (1026 of 5621 strings)

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

powered by weblate
2024-05-22 09:15:52 +02:00
Serhii HorichenkoandRaphael Michel 47a03e1b2a Translations: Update Ukrainian
Currently translated at 63.5% (3573 of 5621 strings)

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

powered by weblate
2024-05-22 09:15:52 +02:00
Raphael Michel 86ddca15ca Keep Python 3.9 compatibility for now / Revert "Fix more Python 3.12 warnings"
This reverts commit 294b3966b0.
2024-05-22 09:02:25 +02:00
Raphael Michel 294b3966b0 Fix more Python 3.12 warnings 2024-05-21 14:40:41 +02:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
fecc00231b Update requests requirement from ==2.31.* to ==2.32.* (#4155)
updated-dependencies:
- dependency-name: requests
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-21 14:24:46 +02:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
b3dfc459f5 Update pep8-naming requirement from ==0.13.* to ==0.14.* (#4152)
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.13.0...0.14.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-21 14:24:25 +02:00
Krisztián Henrik PappandRaphael Michel e21d63a7be Translations: Update Hungarian
Currently translated at 2.0% (115 of 5621 strings)

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

powered by weblate
2024-05-21 14:23:50 +02:00
MiraandGitHub 9a807df158 Fix pretix_event_access (custom domain) sessions for staff users (#4158) 2024-05-21 13:26:12 +02:00
Raphael Michel e95d551711 Silence deprecation warnings on Python 3.12 2024-05-21 12:59:58 +02:00
7188e44fe5 Stripe: Add support for Swish (#4149)
* Stripe: Add support for Swish

* Update src/pretix/plugins/stripe/payment.py

Co-authored-by: Martin Gross <gross@rami.io>

---------

Co-authored-by: Martin Gross <gross@rami.io>
2024-05-17 13:33:03 +02:00
Richard SchreiberandRaphael Michel a6a93555b6 Translations: Update German (informal) (de_Informal)
Currently translated at 100.0% (5621 of 5621 strings)

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

powered by weblate
2024-05-17 11:53:57 +02:00
Richard SchreiberandRaphael Michel 94eb473e42 Translations: Update German
Currently translated at 100.0% (5621 of 5621 strings)

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

powered by weblate
2024-05-17 11:53:57 +02:00
Serhii HorichenkoandRaphael Michel cbc3a344c1 Translations: Update Ukrainian
Currently translated at 98.2% (225 of 229 strings)

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

powered by weblate
2024-05-17 11:53:57 +02:00
Serhii HorichenkoandRaphael Michel 47db52d75f Translations: Update Ukrainian
Currently translated at 63.3% (3559 of 5621 strings)

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

powered by weblate
2024-05-17 11:53:57 +02:00
MiraandGitHub ba99fe597c Use correct condition for time machine check in template (#4151) 2024-05-17 11:29:54 +02:00
b638c00952 Time machine mode [Z#23129725] (#3961)
Allows organizers to test their shop as if it were a different date and time.

Implemented using a time_machine_now() function which is used instead of regular now(), which can overlay the real date time with a value from a ContextVar, assigned from a session value in EventMiddleware.

For more information, see doc/development/implementation/timemachine.rst

---------

Co-authored-by: Richard Schreiber <schreiber@rami.io>
Co-authored-by: Raphael Michel <michel@rami.io>
2024-05-17 10:52:17 +02:00
Raphael Michel bfcca7046a Vouchers: Add copy button for URL 2024-05-16 11:57:50 +02:00
Raphael Michel ad5d10ff67 Fix missing serializer class 2024-05-15 11:01:32 +02:00
Raphael Michel 54d327deea Badges: Fix name clash of cache property 2024-05-15 09:46:56 +02:00
Raphael Michel d6505f946f API: Allow setting payment_giftcard__enabled 2024-05-14 15:45:42 +02:00
Raphael Michel 9c4efa7dcf Fix link on orders with memberships without customer (PRETIXEU-A1W) 2024-05-14 11:59:16 +02:00
Raphael Michel e6d26c4962 Add comment on pypdf upgrade 2024-05-14 11:09:02 +02:00
Serhii HorichenkoandRaphael Michel 7ddbbe21f7 Translations: Update Ukrainian
Currently translated at 62.8% (3534 of 5621 strings)

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

powered by weblate
2024-05-14 11:04:24 +02:00
Serhii HorichenkoandRaphael Michel 8d5ad0bd9e Translations: Update Russian
Currently translated at 19.5% (1101 of 5621 strings)

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

powered by weblate
2024-05-14 11:04:24 +02:00
Raphael Michel aff6a6f022 Revert "Update pypdf requirement from ==3.9.* to ==4.2.* (#4145)"
This reverts commit 46008818ce.
2024-05-14 10:59:43 +02:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
46008818ce Update pypdf requirement from ==3.9.* to ==4.2.* (#4145)
Updates the requirements on [pypdf](https://github.com/py-pdf/pypdf) to permit the latest version.
- [Release notes](https://github.com/py-pdf/pypdf/releases)
- [Changelog](https://github.com/py-pdf/pypdf/blob/main/CHANGELOG.md)
- [Commits](https://github.com/py-pdf/pypdf/compare/3.9.0...4.2.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-14 09:33:26 +02:00
Raphael Michel 95db04bad2 Revert "Update pypdf requirement from ==3.9.* to ==4.2.* (#4055)"
This reverts commit 46b2214836.
2024-05-13 18:29:41 +02:00
Serhii HorichenkoandRaphael Michel d0c62ec1cf Translations: Update Ukrainian
Currently translated at 62.8% (3532 of 5621 strings)

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

powered by weblate
2024-05-13 10:06:04 +02:00
Serhii HorichenkoandRaphael Michel d6cbb130bd Translations: Update Ukrainian
Currently translated at 62.8% (3532 of 5621 strings)

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

powered by weblate
2024-05-13 10:06:04 +02:00
Martin GrossandRaphael Michel 097d2fcda0 Translations: Update Norwegian Bokmål
Currently translated at 97.0% (5455 of 5621 strings)

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

powered by weblate
2024-05-13 10:06:04 +02:00
RyoandRaphael Michel 41a7c13970 Translations: Update Japanese
Currently translated at 3.4% (194 of 5621 strings)

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

powered by weblate
2024-05-13 10:06:04 +02:00
Raphael MichelandRaphael Michel 1b725810dd Translations: Update German (informal) (de_Informal)
Currently translated at 100.0% (5621 of 5621 strings)

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

powered by weblate
2024-05-08 17:54:00 +02:00
Raphael MichelandRaphael Michel 251f486480 Translations: Update German
Currently translated at 100.0% (5621 of 5621 strings)

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

powered by weblate
2024-05-08 17:54:00 +02:00
Adam KaputandRaphael Michel a7afcdf753 Translations: Update Polish
Currently translated at 40.0% (2243 of 5607 strings)

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

powered by weblate
2024-05-08 17:54:00 +02:00
NikolaiandRaphael Michel 0722341073 Translations: Update Danish
Currently translated at 31.1% (1744 of 5607 strings)

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

powered by weblate
2024-05-08 17:54:00 +02:00
Raphael Michel 207bf101b8 Update po files
[CI skip]

Signed-off-by: Raphael Michel <michel@rami.io>
2024-05-08 15:19:10 +02:00
e8f7cea1bf Allow attendees to modify their data (Z#23152886) (#4138)
* Allow attendees to modify their data

* Allow attendees to change ticket information

* Update src/pretix/control/templates/pretixcontrol/event/settings.html

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

* Update src/pretix/presale/views/order.py

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

* Update src/pretix/base/services/placeholders.py

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

* Tests fix

* Fix test

---------

Co-authored-by: Mira <weller@rami.io>
2024-05-08 15:18:33 +02:00
Raphael Michel aa55eb2de2 Reactivate order: Fix incorrect signal being sent 2024-05-08 09:56:37 +02:00
MiraandGitHub 9dc5c1b266 Prevent transferring files from priv/ to pub/ on event clone (#3956)
* Prevent transferring files from priv/ to pub/ on event clone

* Also detect file names with node prefix

* Only transfer files in explicitly declared file fields

* Update django-hierarkey

* Add note to documentation about the new behaviour
2024-05-08 09:33:23 +02:00
Shintaro OkamatsuandRaphael Michel 514f1def4d Translations: Update Japanese
Currently translated at 3.4% (193 of 5607 strings)

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

powered by weblate
2024-05-08 09:32:48 +02:00
AbdelatifAitBaraandRaphael Michel c2bc97a0d8 Translations: Update Arabic
Currently translated at 66.4% (3728 of 5607 strings)

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

powered by weblate
2024-05-08 09:32:48 +02:00
Serhii HorichenkoandRaphael Michel 7fba473426 Translations: Update Ukrainian
Currently translated at 98.2% (225 of 229 strings)

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

powered by weblate
2024-05-08 09:32:48 +02:00
Serhii HorichenkoandRaphael Michel be87ba0000 Translations: Update Ukrainian
Currently translated at 62.9% (3531 of 5607 strings)

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

powered by weblate
2024-05-08 09:32:48 +02:00
Adam KaputandRaphael Michel 76b7643c39 Translations: Update Polish
Currently translated at 94.7% (217 of 229 strings)

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

powered by weblate
2024-05-08 09:32:48 +02:00
Adam KaputandRaphael Michel b1a3963b33 Translations: Update Polish
Currently translated at 39.7% (2226 of 5607 strings)

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

powered by weblate
2024-05-08 09:32:48 +02:00
Raphael MichelandGitHub 586e694ff3 Order import: Add expires column (Z#23152985) (#4137) 2024-05-08 09:09:55 +02:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
f4383c67a4 Update fakeredis requirement from ==2.22.* to ==2.23.* (#4140)
Updates the requirements on [fakeredis](https://github.com/cunla/fakeredis-py) to permit the latest version.
- [Release notes](https://github.com/cunla/fakeredis-py/releases)
- [Commits](https://github.com/cunla/fakeredis-py/compare/v2.22.0...v2.23.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-08 09:07:51 +02:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
46b2214836 Update pypdf requirement from ==3.9.* to ==4.2.* (#4055)
Updates the requirements on [pypdf](https://github.com/py-pdf/pypdf) to permit the latest version.
- [Release notes](https://github.com/py-pdf/pypdf/releases)
- [Changelog](https://github.com/py-pdf/pypdf/blob/main/CHANGELOG.md)
- [Commits](https://github.com/py-pdf/pypdf/compare/3.9.0...4.2.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-07 14:32:48 +02:00
Raphael MichelandGitHub 0e20d897d2 Prevent parallel refunds for the same order (Z#23152965) (#4136) 2024-05-07 14:32:02 +02:00
Raphael Michel 0c09cccd4f Docs: Add docker compose guide 2024-05-07 13:55:52 +02:00
Raphael MichelandGitHub 5ca0833db1 Vouchers: Fix validation of quota when copying a blocking voucher (Z#23152799) (#4133)
* Vouchers: Fix validation of quota when copying a blocking voucher

* Bugfixes
2024-05-07 09:50:16 +02:00
Raphael MichelandGitHub 7a63498333 PDF editor: Add variables for purchase date (Z#23152887) (#4134)
* PDF editor: Add variables for purchase date (Z#23152887)

* Fix order and add time
2024-05-07 09:48:05 +02:00
Raphael Michel b8c0887f79 Widget: Fix CORS for cached JS 2024-05-07 09:31:56 +02:00
Raphael Michel 9da65f60d7 Voucher import: Fix validation quirks 2024-05-03 16:06:40 +02:00
Raphael Michel 806124304a Voucher get code validation 2024-05-03 14:34:51 +02:00
Serhii HorichenkoandRaphael Michel 0d57673a47 Translations: Update Ukrainian
Currently translated at 62.9% (3529 of 5607 strings)

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

powered by weblate
2024-05-03 09:52:42 +02:00
Raphael MichelandGitHub 166b5e4f3b Change default password hash to argon2id (#4121)
* Change default password hash to argon2id

* Install argon2
2024-05-02 18:22:02 +02:00
541b8f5bd6 Discounts: Fix edge case in computation (#4126)
* Add new test case for discounts:

Two discounts:
- "For every 1 item1, you get three item2 for 10 % off."
- "For every 1 item1, you get five item3 for 10 % off."
Cart: 2x item1, 2x item2, 6x item3
Expected result: 2x item1 full price, 2x item2 discounted, 5x item3 discounted, 1x item3 full price

* Fix discount calculation bug

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

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

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

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

---------

Co-authored-by: Raphael Michel <michel@rami.io>
Co-authored-by: Richard Schreiber <schreiber@rami.io>
2024-05-02 18:21:56 +02:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
d2b96b2425 Bump @babel/core from 7.24.3 to 7.24.5 in /src/pretix/static/npm_dir (#4125)
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.24.3 to 7.24.5.
- [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.24.5/packages/babel-core)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-02 18:21:30 +02:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
04d4c4f8f1 Bump @babel/preset-env from 7.24.3 to 7.24.5 in /src/pretix/static/npm_dir (#4124)
Bumps [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env) from 7.24.3 to 7.24.5.
- [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.24.5/packages/babel-preset-env)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-02 16:31:55 +02:00
Raphaël DeuxandRaphael Michel f4da94cbcd Translations: Update French
Currently translated at 96.7% (5424 of 5607 strings)

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

powered by weblate
2024-05-02 16:31:45 +02:00
Serhii HorichenkoandRaphael Michel 97e3d5387f Translations: Update Ukrainian
Currently translated at 98.2% (225 of 229 strings)

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

powered by weblate
2024-05-02 16:31:45 +02:00
Serhii HorichenkoandRaphael Michel 8fc07523a9 Translations: Update Ukrainian
Currently translated at 62.8% (3526 of 5607 strings)

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

powered by weblate
2024-05-02 16:31:45 +02:00
NikolaiandRaphael Michel f18b0ae187 Translations: Update Danish
Currently translated at 31.1% (1744 of 5607 strings)

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

powered by weblate
2024-05-02 16:31:45 +02:00
Raphael Michel f7e16f56ac Revert "Install argon2"
This reverts commit 3f4e869cea.
2024-05-02 16:27:46 +02:00
Raphael Michel 3f4e869cea Install argon2 2024-05-02 16:27:37 +02:00
Martin Gross 8c2a1d58f4 Templates: Add Herma 4515 (Acetatesilk) to repository 2024-05-02 13:57:46 +02:00
155 changed files with 93384 additions and 85804 deletions
+7 -2
View File
@@ -3,11 +3,16 @@
.. _`community`:
Community install guides
================================
========================
.. warning:: The guides are maintained by the community and not by the pretix core team. If you encounter any issues with the guides, please report them to the maintainers of the guides. The pretix core team can not provide support for installs using these guides.
Kubernetes
------------
----------
- Helm Chart by techwolf12 - A Helm chart for deploying pretix on Kubernetes. The chart documentation is available on `ArtifactHub <https://artifacthub.io/packages/helm/techwolf12/pretix>`_ and the source code is available on `GitHub <https://github.com/Techwolf12/charts/tree/main/pretix-helm>`_.
Docker
------
- `docker compose setup <https://github.com/ZPascal/pretix-docker-compose>`_ by ZPascal
+10 -1
View File
@@ -15,7 +15,7 @@ includes serializers for serializing the following types:
* Built-in types: ``int``, ``float``, ``decimal.Decimal``, ``dict``, ``list``, ``bool``
* ``datetime.date``, ``datetime.datetime``, ``datetime.time``
* ``LazyI18nString``
* References to Django ``File`` objects that are already stored in a storage backend
* References to Django ``File`` objects that are already stored in a storage backend [#f1]_
* References to model instances
In code, we recommend to always use the ``.get()`` method on the settings object to access a value, but for
@@ -55,6 +55,9 @@ You can simply use it like this:
"preserve his reservation."),
)
.. _settings-defaults-in-plugins:
Defaults in plugins
-------------------
@@ -70,3 +73,9 @@ Make sure that you include this code in a module that is imported at app loading
.. _django-hierarkey: https://github.com/raphaelm/django-hierarkey
.. _documentation: https://django-hierarkey.readthedocs.io/en/latest/
.. rubric:: Footnotes
.. [#f1] If you store ``File`` instances in per-event settings, make sure to always register them with ``add_default``
as described above in :ref:`settings-defaults-in-plugins`. Otherwise, the file won't get copied properly if the
user copies the settings of an existing event to a new one.
+18 -5
View File
@@ -45,6 +45,8 @@ allow_voucher_access boolean Enables access
lead_scanning_scope_by_device string Enables lead scanning to be handled as one lead per attendee
per scanning device, instead of only per exhibitor.
comment string Internal comment, not shown to exhibitor
exhibitor_tags list of strings Internal tags to categorize exhibitors, not shown to exhibitor.
The tags need to be created through the web interface currently.
===================================== ========================== =======================================================
You can also access the scanned leads through the API which contains the following public fields:
@@ -119,7 +121,8 @@ Endpoints
"allow_lead_scanning": true,
"allow_lead_access": true,
"allow_voucher_access": true,
"comment": ""
"comment": "",
"exhibitor_tags": []
}
]
}
@@ -173,7 +176,8 @@ Endpoints
"allow_lead_scanning": true,
"allow_lead_access": true,
"allow_voucher_access": true,
"comment": ""
"comment": "",
"exhibitor_tags": []
}
:param organizer: The ``slug`` field of the organizer to fetch
@@ -374,7 +378,10 @@ Endpoints
"allow_lead_scanning": true,
"allow_lead_access": true,
"allow_voucher_access": true,
"comment": ""
"comment": "",
"exhibitor_tags": [
"Gold Sponsor"
]
}
**Example response**:
@@ -407,7 +414,10 @@ Endpoints
"allow_lead_scanning": true,
"allow_lead_access": true,
"allow_voucher_access": true,
"comment": ""
"comment": "",
"exhibitor_tags": [
"Gold Sponsor"
]
}
:param organizer: The ``slug`` field of the organizer to create new exhibitor for
@@ -468,7 +478,10 @@ Endpoints
"allow_lead_scanning": true,
"allow_lead_access": true,
"allow_voucher_access": true,
"comment": ""
"comment": "",
"exhibitor_tags": [
"Gold Sponsor"
]
}
:param organizer: The ``slug`` field of the organizer to modify
+3 -3
View File
@@ -339,9 +339,9 @@ Currently, the following attributes are understood by pretix itself:
``data-attendee-name``, which will pre-fill the last part of the name, whatever that is.
* ``data-invoice-address-FIELD`` will pre-fill the corresponding field of the invoice address. Possible values for
``FIELD`` are ``company``, ``street``, ``zipcode``, ``city`` and ``country``, as well as fields specified by the
naming scheme such as ``name-title`` or ``name-given-name`` (see above). ``country`` expects a two-character
country code.
``FIELD`` are ``company``, ``street``, ``zipcode``, ``city``, ``country``, ``internal-reference``, ``vat-id``, and
``custom-field``, as well as fields specified by the naming scheme such as ``name-title`` or ``name-given-name``
(see above). ``country`` expects a two-character country code.
* If ``data-fix="true"`` is given, the user will not be able to change the other given values later. This currently
only works for the order email address as well as the invoice address. Attendee-level fields and questions can
+6 -6
View File
@@ -36,14 +36,14 @@ dependencies = [
"css-inline==0.14.*",
"defusedcsv>=1.1.0",
"dj-static",
"Django==4.2.*",
"Django[argon2]==4.2.*",
"django-bootstrap3==24.2",
"django-compressor==4.4",
"django-countries==7.6.*",
"django-filter==24.2",
"django-formset-js-improved==0.5.0.3",
"django-formtools==2.5.1",
"django-hierarkey==1.1.*",
"django-hierarkey==1.2.*",
"django-hijack==3.4.*",
"django-i18nfield==1.9.*,>=1.9.4",
"django-libsass==0.9",
@@ -77,12 +77,12 @@ dependencies = [
"phonenumberslite==8.13.*",
"Pillow==10.3.*",
"pretix-plugin-build",
"protobuf==5.26.*",
"protobuf==5.27.*",
"psycopg2-binary",
"pycountry",
"pycparser==2.22",
"pycryptodome==3.20.*",
"pypdf==3.9.*",
"pypdf==4.2.*",
"python-bidi==0.4.*", # Support for Arabic in reportlab
"python-dateutil==2.9.*",
"pytz",
@@ -113,11 +113,11 @@ dev = [
"aiohttp==3.9.*",
"coverage",
"coveralls",
"fakeredis==2.22.*",
"fakeredis==2.23.*",
"flake8==7.0.*",
"freezegun",
"isort==5.13.*",
"pep8-naming==0.13.*",
"pep8-naming==0.14.*",
"potypo",
"pytest-asyncio",
"pytest-cache",
+1 -1
View File
@@ -19,4 +19,4 @@
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
# <https://www.gnu.org/licenses/>.
#
__version__ = "2024.5.0.dev0"
__version__ = "2024.6.0.dev0"
+3 -1
View File
@@ -684,8 +684,9 @@ class EventSettingsSerializer(SettingsSerializer):
'locales',
'locale',
'region',
'last_order_modification_date',
'allow_modifications',
'allow_modifications_after_checkin',
'last_order_modification_date',
'show_quota_left',
'waiting_list_enabled',
'waiting_list_auto_disable',
@@ -735,6 +736,7 @@ class EventSettingsSerializer(SettingsSerializer):
'payment_term_accept_late',
'payment_explanation',
'payment_pending_hidden',
'payment_giftcard__enabled',
'mail_days_order_expire_warning',
'ticket_download',
'ticket_download_date',
+2 -2
View File
@@ -1035,7 +1035,7 @@ class BaseInvoiceAddressForm(forms.ModelForm):
self.all_optional = kwargs.pop('all_optional', False)
kwargs.setdefault('initial', {})
if not kwargs.get('instance') or not kwargs['instance'].country:
if (not kwargs.get('instance') or not kwargs['instance'].country) and not kwargs["initial"].get("country"):
kwargs['initial']['country'] = guess_country_from_request(self.request, self.event)
super().__init__(*args, **kwargs)
@@ -1171,7 +1171,7 @@ class BaseInvoiceAddressForm(forms.ModelForm):
self.instance.vat_id_validated = False
messages.warning(self.request, e.message)
else:
raise ValidationError(e.message)
raise ValidationError({"vat_id": e.message})
except VATIDTemporaryError as e:
self.instance.vat_id_validated = False
if self.request and self.vat_warning:
@@ -0,0 +1,24 @@
# Generated by Django 4.2.11 on 2024-05-16 11:07
from django.db import migrations, models
import pretix.base.models.orders
class Migration(migrations.Migration):
dependencies = [
("pretixbase", "0263_auto_20240409_0732"),
]
operations = [
migrations.AddField(
model_name="order",
name="internal_secret",
field=models.CharField(
default=None,
max_length=32,
null=True,
),
),
]
+30 -3
View File
@@ -19,6 +19,7 @@
# 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/>.
#
import datetime
from collections import defaultdict
import pycountry
@@ -26,6 +27,7 @@ from django.conf import settings
from django.core.exceptions import ValidationError
from django.core.validators import EmailValidator
from django.db.models import Q
from django.utils import formats
from django.utils.functional import cached_property
from django.utils.translation import (
gettext as _, gettext_lazy, pgettext, pgettext_lazy,
@@ -509,6 +511,30 @@ class ValidUntil(DatetimeColumnMixin, ImportColumn):
position.valid_until = value
class Expires(DatetimeColumnMixin, ImportColumn):
identifier = 'expires'
verbose_name = gettext_lazy('Expiry date')
def clean(self, value, previous_values):
if not value:
return
input_formats = formats.get_format('DATE_INPUT_FORMATS', use_l10n=True)
for format in input_formats:
try:
d = datetime.datetime.strptime(value, format)
d = d.replace(tzinfo=self.timezone, hour=23, minute=59, second=59)
return d
except (ValueError, TypeError):
pass
else:
return super().clean(value, previous_values) # parse date
def assign(self, value, order, position, invoice_address, **kwargs):
if value:
order.expires = value
class Saleschannel(ImportColumn):
identifier = 'sales_channel'
verbose_name = gettext_lazy('Sales channel')
@@ -702,12 +728,13 @@ def get_order_import_columns(event):
AttendeeState(event),
Price(event),
Secret(event),
Locale(event),
Saleschannel(event),
SeatColumn(event),
Comment(event),
ValidFrom(event),
ValidUntil(event),
Locale(event),
Saleschannel(event),
Expires(event),
Comment(event),
]
for q in event.questions.prefetch_related('options').exclude(type=Question.TYPE_FILE):
default.append(QuestionColumn(event, q))
+1 -3
View File
@@ -44,8 +44,6 @@ class CodeColumn(ImportColumn):
super().__init__(*args)
def clean(self, value, previous_values):
if not value:
raise ValidationError(_('A voucher cannot be created without a code.'))
if value:
MinLengthValidator(5)(value)
if value and (value in self._cached or Voucher.objects.filter(event=self.event, code=value).exists()):
@@ -77,7 +75,7 @@ class MaxUsagesColumn(IntegerColumnMixin, ImportColumn):
]
def clean(self, value, previous_values):
if value is None:
if value is None and previous_values.get("code"):
raise ValidationError(_('The maximum number of usages must be set.'))
return super().clean(value, previous_values)
+7 -3
View File
@@ -418,18 +418,22 @@ class User(AbstractBaseUser, PermissionsMixin, LoggingMixin):
else:
return set()
def has_event_permission(self, organizer, event, perm_name=None, request=None) -> bool:
def has_event_permission(self, organizer, event, perm_name=None, request=None, session_key=None) -> bool:
"""
Checks if this user is part of any team that grants access of type ``perm_name``
to the event ``event``.
Either ``request`` or ``session_key`` are required to detect staff sessions properly.
:param organizer: The organizer of the event
:param event: The event to check
:param perm_name: The permission, e.g. ``can_change_teams``
:param request: The current request (optional). Required to detect staff sessions properly.
:param request: The current request (optional)
:param session_key: The current session key (optional)
:return: bool
"""
if request and self.has_active_staff_session(request.session.session_key):
assert not (session_key and request)
if (session_key or request) and self.has_active_staff_session(session_key or request.session.session_key):
return True
teams = self._get_teams_for_event(organizer, event)
if teams:
+2 -1
View File
@@ -23,6 +23,7 @@
from collections import defaultdict
from decimal import Decimal
from itertools import groupby
from math import ceil
from typing import Dict, Optional, Tuple
from django.core.exceptions import ValidationError
@@ -272,7 +273,7 @@ class Discount(LoggedModel):
# Prevent over-consuming of items, i.e. if our discount is "buy 2, get 1 free", we only
# want to match multiples of 3
n_groups = min(len(condition_idx_group) // self.condition_min_count, len(benefit_idx_group))
n_groups = min(len(condition_idx_group) // self.condition_min_count, ceil(len(benefit_idx_group) / self.benefit_only_apply_to_cheapest_n_matches))
consume_idx = condition_idx_group[:n_groups * self.condition_min_count]
benefit_idx = benefit_idx_group[:n_groups * self.benefit_only_apply_to_cheapest_n_matches]
else:
+2 -1
View File
@@ -45,6 +45,7 @@ from zoneinfo import ZoneInfo
import pytz_deprecation_shim
from django.conf import settings
from django.core.exceptions import ValidationError
from django.core.files import File
from django.core.files.storage import default_storage
from django.core.mail import get_connection
from django.core.validators import (
@@ -1026,7 +1027,7 @@ class Event(EventMixin, LoggedModel):
s.object = self
s.pk = None
if s.value.startswith('file://'):
if s.value.startswith('file://') and settings_hierarkey.get_declared_type(s.key) == File:
fi = default_storage.open(s.value[len('file://'):], 'rb')
nonce = get_random_string(length=8)
fname_base = clean_filename(os.path.basename(s.value))
+76 -2
View File
@@ -35,6 +35,7 @@
import copy
import hashlib
import hmac
import json
import logging
import operator
@@ -59,7 +60,7 @@ from django.db.models.functions import Coalesce, Greatest
from django.db.models.signals import post_delete
from django.dispatch import receiver
from django.urls import reverse
from django.utils.crypto import get_random_string
from django.utils.crypto import get_random_string, salted_hmac
from django.utils.encoding import escape_uri_path
from django.utils.formats import date_format
from django.utils.functional import cached_property
@@ -105,6 +106,34 @@ def generate_position_secret():
raise TypeError("Function no longer exists, use secret generators")
class OrderQuerySet(models.QuerySet):
def get_with_secret_check(self, code, received_secret, tag, secret_length=64):
dummy = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"[:secret_length]
try:
order = self.get(code=code)
except Order.DoesNotExist:
# Do a hash comparison as well to harden against timing attacks
hmac.compare_digest(
salted_hmac(key_salt=b"", value=tag, algorithm="sha256",
secret=dummy).hexdigest()[:secret_length],
received_secret[:secret_length]
)
raise Order.DoesNotExist
if not hmac.compare_digest(
order.tagged_secret(tag, secret_length) if tag else order.secret,
received_secret[:secret_length].lower() if tag else received_secret.lower()
) and not (
# TODO: remove this clause after a while (compatibility with old secrets currently in flight)
tag and hmac.compare_digest(
hashlib.sha1(order.secret.lower().encode()).hexdigest(),
received_secret.lower()
)
):
raise Order.DoesNotExist
return order
class Order(LockModel, LoggedModel):
"""
An order is created when a user clicks 'buy' on his cart. It holds
@@ -223,6 +252,7 @@ class Order(LockModel, LoggedModel):
verbose_name=_('Locale')
)
secret = models.CharField(max_length=32, default=generate_secret)
internal_secret = models.CharField(null=True, blank=True, max_length=32, default=generate_secret)
datetime = models.DateTimeField(
verbose_name=_("Date"), db_index=False
)
@@ -285,7 +315,7 @@ class Order(LockModel, LoggedModel):
default=False,
)
objects = ScopedManager(organizer='event__organizer')
objects = ScopedManager(OrderQuerySet.as_manager().__class__, organizer='event__organizer')
class Meta:
verbose_name = _("Order")
@@ -851,6 +881,9 @@ class Order(LockModel, LoggedModel):
if self.status not in (Order.STATUS_PENDING, Order.STATUS_PAID, Order.STATUS_EXPIRED):
return False
if self.event.settings.allow_modifications not in ("order", "attendee"):
return False
modify_deadline = self.modify_deadline
if modify_deadline is not None and time_machine_now() > modify_deadline:
return False
@@ -1220,6 +1253,10 @@ class Order(LockModel, LoggedModel):
_transactions_mark_order_clean(self.pk)
return create
def tagged_secret(self, tag, secret_length=64):
return salted_hmac(value=tag, key_salt=b"", algorithm="sha256",
secret=self.internal_secret or self.secret).hexdigest()[:secret_length]
def answerfile_name(instance, filename: str) -> str:
secret = get_random_string(length=32, allowed_chars=string.ascii_letters + string.digits)
@@ -2514,6 +2551,43 @@ class OrderPosition(AbstractPosition):
reasons[b] = b
return reasons
@property
def can_modify_answers(self) -> bool:
"""
``True`` if the user can change the question answers / attendee names that are
related to the position. This checks order status and modification deadlines. It also
returns ``False`` if there are no questions that can be answered.
"""
from .checkin import Checkin
if self.order.status not in (Order.STATUS_PENDING, Order.STATUS_PAID, Order.STATUS_EXPIRED):
return False
if self.event.settings.allow_modifications != "attendee":
return False
modify_deadline = self.order.modify_deadline
if modify_deadline is not None and now() > modify_deadline:
return False
positions = list(
self.order.positions.all().annotate(
has_checkin=Exists(Checkin.objects.filter(position_id=OuterRef('pk'), list__consider_tickets_used=True))
).select_related('item').prefetch_related('item__questions')
)
if not self.event.settings.allow_modifications_after_checkin:
for cp in positions:
if cp.has_checkin:
return False
ask_names = self.event.settings.get('attendee_names_asked', as_type=bool)
for cp in positions:
if cp.pk == self.pk or cp.addon_to_id == self.pk:
if (cp.item.ask_attendee_data and ask_names) or cp.item.questions.all():
return True
return False # nothing there to modify
@classmethod
def transform_cart_positions(cls, cp: List, order) -> list:
from . import Voucher
+6 -5
View File
@@ -370,10 +370,11 @@ class Voucher(LoggedModel):
'redeemed': redeemed
}
)
if data.get('max_usages', 1) < data.get('min_usages', 1):
raise ValidationError(
_('The maximum number of usages may not be lower than the minimum number of usages.'),
)
if data.get('min_usages') is not None:
if data.get('max_usages', 1) < data.get('min_usages', 1):
raise ValidationError(
_('The maximum number of usages may not be lower than the minimum number of usages.'),
)
@staticmethod
def clean_subevent(data, event):
@@ -459,7 +460,7 @@ class Voucher(LoggedModel):
new_quotas = set(
Quota.objects.filter(
pk__in=Quota.variations.through.objects.filter(
itemvariation__item=old_instance.item,
itemvariation__item=item,
quota__subevent=data.get('subevent'),
).values('quota_id')
)
+35 -54
View File
@@ -62,8 +62,7 @@ from django.utils.html import conditional_escape
from django.utils.timezone import now
from django.utils.translation import gettext_lazy as _, pgettext
from i18nfield.strings import LazyI18nString
from pypdf import PdfReader, PdfWriter, Transformation
from pypdf.generic import RectangleObject
from pypdf import PdfReader, PdfWriter
from reportlab.graphics import renderPDF
from reportlab.graphics.barcode.qr import QrCodeWidget
from reportlab.graphics.shapes import Drawing
@@ -408,6 +407,30 @@ DEFAULT_VARIABLES = OrderedDict((
"TIME_FORMAT"
)
}),
("purchase_date", {
"label": _("Purchase date"),
"editor_sample": _("2017-05-31"),
"evaluate": lambda op, order, ev: date_format(
order.datetime.astimezone(ev.timezone),
"SHORT_DATE_FORMAT"
)
}),
("purchase_datetime", {
"label": _("Purchase date and time"),
"editor_sample": _("2017-05-31 19:00"),
"evaluate": lambda op, order, ev: date_format(
order.datetime.astimezone(ev.timezone),
"SHORT_DATETIME_FORMAT"
)
}),
("purchase_time", {
"label": _("Purchase time"),
"editor_sample": _("19:00"),
"evaluate": lambda op, order, ev: date_format(
order.datetime.astimezone(ev.timezone),
"TIME_FORMAT"
)
}),
("valid_from_date", {
"label": _("Validity start date"),
"editor_sample": _("2017-05-31"),
@@ -1069,32 +1092,11 @@ class Renderer:
output = PdfWriter()
for i, page in enumerate(new_pdf.pages):
bg_page = copy.deepcopy(self.bg_pdf.pages[i])
bg_rotation = bg_page.get('/Rotate')
if bg_rotation:
# /Rotate is clockwise, transformation.rotate is counter-clockwise
t = Transformation().rotate(bg_rotation)
w = float(page.mediabox.getWidth())
h = float(page.mediabox.getHeight())
if bg_rotation in (90, 270):
# offset due to rotation base
if bg_rotation == 90:
t = t.translate(h, 0)
else:
t = t.translate(0, w)
# rotate mediabox as well
page.mediabox = RectangleObject((
page.mediabox.left.as_numeric(),
page.mediabox.bottom.as_numeric(),
page.mediabox.top.as_numeric(),
page.mediabox.right.as_numeric(),
))
page.trimbox = page.mediabox
elif bg_rotation == 180:
t = t.translate(w, h)
page.add_transformation(t)
bg_page.merge_page(page)
output.add_page(bg_page)
bg_page = self.bg_pdf.pages[i]
if bg_page.rotation != 0:
bg_page.transfer_rotation_to_content()
page.merge_page(bg_page, over=False)
output.add_page(page)
output.add_metadata({
'/Title': str(title),
@@ -1127,32 +1129,11 @@ def merge_background(fg_pdf, bg_pdf, out_file, compress):
else:
output = PdfWriter()
for i, page in enumerate(fg_pdf.pages):
bg_page = copy.deepcopy(bg_pdf.pages[i])
bg_rotation = bg_page.get('/Rotate')
if bg_rotation:
# /Rotate is clockwise, transformation.rotate is counter-clockwise
t = Transformation().rotate(bg_rotation)
w = float(page.mediabox.getWidth())
h = float(page.mediabox.getHeight())
if bg_rotation in (90, 270):
# offset due to rotation base
if bg_rotation == 90:
t = t.translate(h, 0)
else:
t = t.translate(0, w)
# rotate mediabox as well
page.mediabox = RectangleObject((
page.mediabox.left.as_numeric(),
page.mediabox.bottom.as_numeric(),
page.mediabox.top.as_numeric(),
page.mediabox.right.as_numeric(),
))
page.trimbox = page.mediabox
elif bg_rotation == 180:
t = t.translate(w, h)
page.add_transformation(t)
bg_page.merge_page(page)
output.add_page(bg_page)
bg_page = bg_pdf.pages[i]
if bg_page.rotation != 0:
bg_page.transfer_rotation_to_content()
page.merge_page(bg_page, over=False)
output.add_page(page)
output.write(out_file)
+2
View File
@@ -213,6 +213,8 @@ def import_vouchers(event: Event, fileid: str, settings: dict, locale: str, user
voucher = Voucher(event=event)
vouchers.append(voucher)
if not record.get("code"):
raise ValidationError(_('A voucher cannot be created without a code.'))
Voucher.clean_item_properties(
record,
event,
+3 -3
View File
@@ -99,8 +99,8 @@ from pretix.base.services.quotas import QuotaAvailability
from pretix.base.services.tasks import ProfiledEventTask, ProfiledTask
from pretix.base.signals import (
order_approved, order_canceled, order_changed, order_denied, order_expired,
order_fee_calculation, order_paid, order_placed, order_split,
order_valid_if_pending, periodic_task, validate_order,
order_fee_calculation, order_paid, order_placed, order_reactivated,
order_split, order_valid_if_pending, periodic_task, validate_order,
)
from pretix.base.timemachine import time_machine_now, time_machine_now_assigned
from pretix.celery_app import app
@@ -254,7 +254,7 @@ def reactivate_order(order: Order, force: bool=False, user: User=None, auth=None
else:
raise OrderError(is_available)
order_approved.send(order.event, order=order)
order_reactivated.send(order.event, order=order)
if order.status == Order.STATUS_PAID:
order_paid.send(order.event, order=order)
+34
View File
@@ -337,6 +337,40 @@ def base_placeholders(sender, **kwargs):
}
),
),
SimpleFunctionalTextPlaceholder(
'url_info_change', ['position', 'event'], lambda position, event: build_absolute_uri(
event,
'presale:event.order.position.modify', kwargs={
'order': position.order.code,
'secret': position.web_secret,
'position': position.positionid
}
), lambda event: build_absolute_uri(
event,
'presale:event.order.position.modify', kwargs={
'order': 'F8VVL',
'secret': '6zzjnumtsx136ddy',
'position': '123',
}
),
),
SimpleFunctionalTextPlaceholder(
'url_products_change', ['position', 'event'], lambda position, event: build_absolute_uri(
event,
'presale:event.order.position.change', kwargs={
'order': position.order.code,
'secret': position.web_secret,
'position': position.positionid
}
), lambda event: build_absolute_uri(
event,
'presale:event.order.position.change', kwargs={
'order': 'F8VVL',
'secret': '6zzjnumtsx136ddy',
'position': '123'
}
),
),
SimpleFunctionalTextPlaceholder(
'order_modification_deadline_date_and_time', ['order', 'event'],
lambda order, event:
+4 -1
View File
@@ -62,7 +62,10 @@ class VATIDTemporaryError(VATIDError):
def _validate_vat_id_NO(vat_id, country_code):
# Inspired by vat_moss library
vat_id = vat_moss.id.normalize(vat_id)
try:
vat_id = vat_moss.id.normalize(vat_id)
except ValueError:
raise VATIDFinalError(error_messages['invalid'])
if not vat_id or len(vat_id) < 3 or not re.match('^\\d{9}MVA$', vat_id[2:]):
raise VATIDFinalError(error_messages['invalid'])
+30 -20
View File
@@ -20,6 +20,7 @@
# <https://www.gnu.org/licenses/>.
#
import sys
from collections import defaultdict
from datetime import timedelta
from django.db import transaction
@@ -49,19 +50,28 @@ def assign_automatically(event: Event, user_id: int=None, subevent_id: int=None)
quota_cache = {}
gone = set()
seats_available = {}
_seats_available_cache = {}
seats_used = defaultdict(int)
for m in SeatCategoryMapping.objects.filter(event=event).select_related('subevent'):
seated_product_set = set(
SeatCategoryMapping.objects.filter(event=event).values_list('product_id', 'subevent_id')
)
def _seats_available(item, subevent):
# See comment in WaitingListEntry.send_voucher() for rationale
num_free_seets_for_product = (m.subevent or event).free_seats().filter(product_id=m.product_id).count()
num_valid_vouchers_for_product = event.vouchers.filter(
Q(valid_until__isnull=True) | Q(valid_until__gte=now()),
block_quota=True,
item_id=m.product_id,
subevent_id=m.subevent_id,
waitinglistentries__isnull=False
).aggregate(free=Sum(F('max_usages') - F('redeemed')))['free'] or 0
seats_available[(m.product_id, m.subevent_id)] = num_free_seets_for_product - num_valid_vouchers_for_product
subevent_id = subevent.pk if subevent else None
if (item.pk, subevent_id) not in _seats_available_cache:
num_free_seats_for_product = (subevent or event).free_seats().filter(product_id=item.pk).count()
num_valid_vouchers_for_product = event.vouchers.filter(
Q(valid_until__isnull=True) | Q(valid_until__gte=now()),
block_quota=True,
item_id=item.pk,
subevent_id=subevent_id,
waitinglistentries__isnull=False
).aggregate(free=Sum(F('max_usages') - F('redeemed')))['free'] or 0
_seats_available_cache[item.pk, subevent_id] = num_free_seats_for_product - num_valid_vouchers_for_product
return _seats_available_cache[item.pk, subevent_id] - seats_used[item.pk, subevent_id]
prefetch_related_objects(
[event.organizer],
@@ -103,7 +113,7 @@ def assign_automatically(event: Event, user_id: int=None, subevent_id: int=None)
lock_objects(quotas, shared_lock_objects=[event])
for wle in qs:
if (wle.item, wle.variation, wle.subevent) in gone:
if (wle.item_id, wle.variation_id, wle.subevent_id) in gone:
continue
ev = (wle.subevent or event)
if not ev.presale_is_running or (wle.subevent and not wle.subevent.active):
@@ -111,15 +121,15 @@ def assign_automatically(event: Event, user_id: int=None, subevent_id: int=None)
if wle.subevent and not wle.subevent.presale_is_running:
continue
if event.settings.waiting_list_auto_disable and event.settings.waiting_list_auto_disable.datetime(wle.subevent or event) <= now():
gone.add((wle.item, wle.variation, wle.subevent))
gone.add((wle.item_id, wle.variation_id, wle.subevent_id))
continue
if not wle.item.is_available():
gone.add((wle.item, wle.variation, wle.subevent))
gone.add((wle.item_id, wle.variation_id, wle.subevent_id))
continue
if (wle.item_id, wle.subevent_id) in seats_available:
if seats_available[wle.item_id, wle.subevent_id] < 1:
gone.add((wle.item, wle.variation, wle.subevent))
if (wle.item_id, wle.subevent_id) in seated_product_set:
if _seats_available(wle.item, wle.subevent) < 1:
gone.add((wle.item_id, wle.variation_id, wle.subevent_id))
continue
availability = (
@@ -141,10 +151,10 @@ def assign_automatically(event: Event, user_id: int=None, subevent_id: int=None)
quota_cache[q.pk][1] - 1 if quota_cache[q.pk][1] is not None else sys.maxsize
)
if (wle.item_id, wle.subevent_id) in seats_available:
seats_available[wle.item_id, wle.subevent_id] -= 1
if (wle.item_id, wle.subevent_id) in seated_product_set:
seats_used[wle.item_id, wle.subevent_id] += 1
else:
gone.add((wle.item, wle.variation, wle.subevent))
gone.add((wle.item_id, wle.variation_id, wle.subevent_id))
return sent
+26 -1
View File
@@ -971,7 +971,8 @@ DEFAULTS = {
},
'payment_giftcard__enabled': {
'default': 'True',
'type': bool
'type': bool,
'serializer_class': serializers.BooleanField,
},
'payment_giftcard_public_name': {
'default': LazyI18nString.from_gettext(gettext_noop('Gift card')),
@@ -1653,6 +1654,28 @@ DEFAULTS = {
"calendar.")
)
},
'allow_modifications': {
'default': 'order',
'type': str,
'form_class': forms.ChoiceField,
'serializer_class': serializers.ChoiceField,
'serializer_kwargs': dict(
choices=(
('no', _('No modifications after order was submitted')),
('order', _('Only the person who ordered can make changes')),
('attendee', _('Both the attendee and the person who ordered can make changes')),
)
),
'form_kwargs': dict(
label=_("Allow customers to modify their information"),
widget=forms.RadioSelect,
choices=(
('no', _('No modifications after order was submitted')),
('order', _('Only the person who ordered can make changes')),
('attendee', _('Both the attendee and the person who ordered can make changes')),
)
),
},
'allow_modifications_after_checkin': {
'default': 'False',
'type': bool,
@@ -1660,6 +1683,8 @@ DEFAULTS = {
'serializer_class': serializers.BooleanField,
'form_kwargs': dict(
label=_("Allow customers to modify their information after they checked in."),
help_text=_("By default, no more modifications are possible for an order as soon as one of the tickets "
"in the order has been checked in.")
)
},
'last_order_modification_date': {
+2 -1
View File
@@ -81,5 +81,6 @@ def has_time_machine_permission(request, event):
) or (
getattr(request, 'event_access_user', None) and
request.event_access_user.is_authenticated and
request.event_access_user.has_event_permission(request.organizer, request.event, permission, request=request)
request.event_access_user.has_event_permission(request.organizer, request.event, permission,
session_key=request.event_access_parent_session_key)
)
+1
View File
@@ -580,6 +580,7 @@ class EventSettingsForm(EventSettingsValidationMixin, FormPlaceholderMixin, Sett
'banner_text',
'banner_text_bottom',
'order_email_asked_twice',
'allow_modifications',
'last_order_modification_date',
'allow_modifications_after_checkin',
'checkout_show_copy_answers_button',
+5 -5
View File
@@ -90,8 +90,10 @@ class VoucherForm(I18nModelForm):
def __init__(self, *args, **kwargs):
instance = kwargs.get('instance')
initial = kwargs.get('initial')
self.initial_instance_data = None
if instance:
self.initial_instance_data = modelcopy(instance)
if instance.pk:
self.initial_instance_data = modelcopy(instance)
try:
if instance.variation:
initial['itemvar'] = '%d-%d' % (instance.item.pk, instance.variation.pk)
@@ -101,8 +103,6 @@ class VoucherForm(I18nModelForm):
initial['itemvar'] = 'q-%d' % instance.quota.pk
except Item.DoesNotExist:
pass
else:
self.initial_instance_data = None
super().__init__(*args, **kwargs)
if instance.event.has_subevents:
@@ -234,8 +234,8 @@ class VoucherForm(I18nModelForm):
)
if check_quota:
Voucher.clean_quota_check(
data, cnt, self.initial_instance_data, self.instance.event,
self.instance.quota, self.instance.item, self.instance.variation
data, cnt, self.initial_instance_data,
self.instance.event, self.instance.quota, self.instance.item, self.instance.variation
)
Voucher.clean_voucher_code(data, self.instance.event, self.instance.pk)
if 'seat' in self.fields and data.get('seat'):
@@ -113,10 +113,17 @@
</div>
{% bootstrap_field sform.attendee_data_explanation_text layout="control" %}
<h4>{% trans "Other settings" %}</h4>
<h4>{% trans "Form settings" %}</h4>
{% bootstrap_field sform.name_scheme layout="control" %}
{% bootstrap_field sform.name_scheme_titles layout="control" %}
{% bootstrap_field sform.checkout_show_copy_answers_button layout="control" %}
<h4>{% trans "Changes to existing orders" %}</h4>
{% bootstrap_field sform.allow_modifications layout="control" %}
<div data-display-dependency='#id_settings-allow_modifications_0' data-inverse>
{% bootstrap_field sform.last_order_modification_date layout="control" %}
{% bootstrap_field sform.allow_modifications_after_checkin layout="control" %}
</div>
</fieldset>
<fieldset>
<legend>{% trans "Texts" %}</legend>
@@ -225,21 +232,47 @@
{% bootstrap_field sform.presale_start_show_date layout="control" %}
{% bootstrap_field form.presale_end layout="control" %}
{% bootstrap_field sform.show_items_outside_presale_period layout="control" %}
{% bootstrap_field sform.last_order_modification_date layout="control" %}
{% bootstrap_field sform.allow_modifications_after_checkin layout="control" %}
{% bootstrap_field sform.show_checkin_number_user layout="control" %}
</fieldset>
<fieldset>
<legend>{% trans "Display" %}</legend>
<h4>{% trans "Date and time" %}</h4>
{% bootstrap_field sform.show_dates_on_frontpage layout="control" %}
{% bootstrap_field sform.show_date_to layout="control" %}
{% bootstrap_field sform.show_times layout="control" %}
<h4>{% trans "Product list" %}</h4>
{% bootstrap_field sform.show_quota_left layout="control" %}
{% bootstrap_field sform.display_net_prices layout="control" %}
{% bootstrap_field sform.hide_prices_from_attendees layout="control" %}
{% bootstrap_field sform.show_variations_expanded layout="control" %}
{% bootstrap_field sform.hide_sold_out layout="control" %}
<h4>{% trans "Calendar and list views" context "subevents" %}</h4>
{% if sform.frontpage_subevent_ordering %}
{% bootstrap_field sform.frontpage_subevent_ordering layout="control" %}
{% endif %}
{% if sform.event_list_type %}
{% bootstrap_field sform.event_list_type layout="control" %}
{% endif %}
{% if sform.event_list_available_only %}
{% bootstrap_field sform.event_list_available_only layout="control" %}
{% endif %}
{% if sform.event_list_filters %}
{% bootstrap_field sform.event_list_filters layout="control" %}
{% endif %}
{% if sform.event_calendar_future_only %}
{% bootstrap_field sform.event_calendar_future_only layout="control" %}
{% endif %}
{% bootstrap_field sform.low_availability_percentage layout="control" addon_after="%" %}
<h4>{% trans "Order details" %}</h4>
{% bootstrap_field sform.hide_prices_from_attendees layout="control" %}
{% bootstrap_field sform.show_checkin_number_user layout="control" %}
<h4>{% trans "Other settings" %}</h4>
{% url "control:organizer.edit" organizer=request.organizer.slug as org_url %}
{% propagated request.event org_url "meta_noindex" %}
{% bootstrap_field sform.meta_noindex layout="control" %}
{% endpropagated %}
<div class="form-group">
<label class="col-md-3 control-label">
{% trans "Footer links" %}<br>
@@ -306,28 +339,6 @@
</div>
</div>
</div>
{% if sform.frontpage_subevent_ordering %}
{% bootstrap_field sform.frontpage_subevent_ordering layout="control" %}
{% endif %}
{% if sform.event_list_type %}
{% bootstrap_field sform.event_list_type layout="control" %}
{% endif %}
{% if sform.event_list_available_only %}
{% bootstrap_field sform.event_list_available_only layout="control" %}
{% endif %}
{% if sform.event_list_filters %}
{% bootstrap_field sform.event_list_filters layout="control" %}
{% endif %}
{% if sform.event_calendar_future_only %}
{% bootstrap_field sform.event_calendar_future_only layout="control" %}
{% endif %}
{% bootstrap_field sform.low_availability_percentage layout="control" addon_after="%" %}
{% url "control:organizer.edit" organizer=request.organizer.slug as org_url %}
{% propagated request.event org_url "meta_noindex" %}
{% bootstrap_field sform.meta_noindex layout="control" %}
{% endpropagated %}
</fieldset>
<fieldset>
<legend>{% trans "Cart" %}</legend>
@@ -436,7 +436,7 @@
{% endif %}
{% if line.used_membership %}
<br /><span class="fa fa-id-card fa-fw" aria-hidden="true"></span>
<a href="{% url "control:organizer.customer.membership.edit" organizer=request.organizer.slug customer=order.customer.identifier id=line.used_membership.pk %}">
<a href="{% url "control:organizer.customer.membership.edit" organizer=request.organizer.slug customer=line.used_membership.customer.identifier id=line.used_membership.pk %}">
{{ line.used_membership }}
</a>
{% endif %}
@@ -192,6 +192,7 @@
<input type="hidden" name="start-action" value="{{ start_form.cleaned_data.action }}">
<input type="hidden" name="start-mode" value="{{ start_form.cleaned_data.mode }}">
<input type="hidden" name="start-partial_amount" value="{{ partial_amount }}">
<input type="hidden" name="last_known_refund_id" value="{{ last_known_refund_id }}">
<div class="form-group">
<label class="control-label" for="id_comment">{% trans "Refund reason" %}</label>
@@ -48,6 +48,12 @@
class="form-control"
id="id_url" readonly>
<div class="input-group-btn">
<button type="button" class="btn btn-default btn-clipboard" data-clipboard-target="#id_url">
<i class="fa fa-clipboard" aria-hidden="true"></i>
<span class="sr-only">
{% trans "Copy" %}
</span>
</button>
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" title="{% trans "Create QR code" %}" aria-haspopup="true" aria-expanded="false">
<i class="fa fa-qrcode" aria-hidden="true"></i>
</button>
+31 -12
View File
@@ -749,21 +749,40 @@ class MailSettingsPreview(EventPermissionRequiredMixin, View):
if preview_item not in MailSettingsForm.base_context:
return HttpResponseBadRequest(_('invalid item'))
regex = r"^" + re.escape(preview_item) + r"_(?P<idx>[\d]+)$"
re_escape_single_bracket = r"((\{)[^\}]+\{|\}[^\{]+(\})|(\{)[^\}]*$|^[^\{]*(\}))"
msgs = {}
for k, v in request.POST.items():
# only accept allowed fields
matched = re.search(regex, k)
if matched is not None:
idx = matched.group('idx')
if idx in self.supported_locale:
with language(self.supported_locale[idx], self.request.event.settings.region):
if k.startswith('mail_subject_'):
msgs[self.supported_locale[idx]] = format_map(bleach.clean(v), self.placeholders(preview_item))
else:
msgs[self.supported_locale[idx]] = markdown_compile_email(
format_map(v, self.placeholders(preview_item))
)
if not k.startswith(preview_item + "_"):
continue
idx = k[len(preview_item)+1:]
if idx in self.supported_locale:
cleaned_v = ""
test_v = v.replace("{{", "__").replace("}}", "__")
while True:
match = re.search(re_escape_single_bracket, test_v)
if not match:
cleaned_v += v
break
if "{" in match.groups():
# replace first occurrence of { with {{, but keep trailing { in testing string
match_end = match.end()-1
cleaned_v += v[:match_end].replace("{", "{{", 1)
else:
# replace last occurrence of } with }}
match_end = match.end()
cleaned_v += "}}".join(v[:match_end].rsplit("}", 1))
v = v[match_end:]
test_v = test_v[match_end:]
with language(self.supported_locale[idx], self.request.event.settings.region):
if k.startswith('mail_subject_'):
msgs[self.supported_locale[idx]] = format_map(bleach.clean(cleaned_v), self.placeholders(preview_item))
else:
msgs[self.supported_locale[idx]] = markdown_compile_email(
format_map(cleaned_v, self.placeholders(preview_item))
)
return JsonResponse({
'item': preview_item,
+260 -245
View File
@@ -49,7 +49,7 @@ from django.core.exceptions import PermissionDenied, ValidationError
from django.core.files import File
from django.db import transaction
from django.db.models import (
Count, Exists, F, IntegerField, OuterRef, Prefetch, ProtectedError, Q,
Count, Exists, F, IntegerField, Max, OuterRef, Prefetch, ProtectedError, Q,
QuerySet, Subquery, Sum,
)
from django.forms import formset_factory
@@ -1104,249 +1104,9 @@ class OrderRefundView(OrderView):
p.propose_refund = proposals.get(p, 0)
if 'perform' in self.request.POST:
refund_selected = Decimal('0.00')
refunds = []
is_valid = True
manual_value = self.request.POST.get('refund-manual', '0') or '0'
manual_value = formats.sanitize_separators(manual_value)
try:
manual_value = Decimal(manual_value)
except (DecimalException, TypeError):
messages.error(self.request, _('You entered an invalid number.'))
is_valid = False
else:
refund_selected += manual_value
if manual_value:
refunds.append(OrderRefund(
order=self.order,
payment=None,
source=OrderRefund.REFUND_SOURCE_ADMIN,
state=(
OrderRefund.REFUND_STATE_DONE
if self.request.POST.get('manual_state') == 'done'
else OrderRefund.REFUND_STATE_CREATED
),
execution_date=(
now()
if self.request.POST.get('manual_state') == 'done'
else None
),
amount=manual_value,
comment=comment,
provider='manual'
))
giftcard_value = self.request.POST.get('refund-new-giftcard', '0') or '0'
giftcard_value = formats.sanitize_separators(giftcard_value)
try:
giftcard_value = Decimal(giftcard_value)
except (DecimalException, TypeError):
messages.error(self.request, _('You entered an invalid number.'))
is_valid = False
else:
if giftcard_value:
refund_selected += giftcard_value
if self.request.POST.get('giftcard-expires'):
try:
expires = forms.DateField().to_python(self.request.POST.get('giftcard-expires'))
expires = make_aware(datetime.combine(
expires,
time(hour=23, minute=59, second=59)
), self.request.event.timezone)
except ValidationError as e:
messages.error(self.request, e.message)
is_valid = False
else:
expires = None
giftcard = self.request.organizer.issued_gift_cards.create(
expires=expires,
currency=self.request.event.currency,
testmode=self.order.testmode
)
giftcard.log_action('pretix.giftcards.created', user=self.request.user, data={})
refunds.append(OrderRefund(
order=self.order,
payment=None,
source=OrderRefund.REFUND_SOURCE_ADMIN,
state=OrderRefund.REFUND_STATE_CREATED,
execution_date=now(),
amount=giftcard_value,
provider='giftcard',
comment=comment,
info=json.dumps({
'gift_card': giftcard.pk
})
))
offsetting_value = self.request.POST.get('refund-offsetting', '0') or '0'
offsetting_value = formats.sanitize_separators(offsetting_value)
try:
offsetting_value = Decimal(offsetting_value)
except (DecimalException, TypeError):
messages.error(self.request, _('You entered an invalid number.'))
is_valid = False
else:
if offsetting_value:
refund_selected += offsetting_value
try:
order = Order.objects.get(code=self.request.POST.get('order-offsetting'),
event__organizer=self.request.organizer)
except Order.DoesNotExist:
messages.error(self.request, _('You entered an order that could not be found.'))
is_valid = False
else:
if order.event.currency != self.request.event.currency:
messages.error(self.request, _('You entered an order in an event with a different currency.'))
is_valid = False
refunds.append(OrderRefund(
order=self.order,
payment=None,
source=OrderRefund.REFUND_SOURCE_ADMIN,
state=OrderRefund.REFUND_STATE_DONE,
execution_date=now(),
amount=offsetting_value,
provider='offsetting',
comment=comment,
info=json.dumps({
'orders': [order.code]
})
))
for identifier, prov in self.request.event.get_payment_providers().items():
prof_value = self.request.POST.get(f'newrefund-{identifier}', '0') or '0'
prof_value = formats.sanitize_separators(prof_value)
try:
prof_value = Decimal(prof_value)
except (DecimalException, TypeError):
messages.error(self.request, _('You entered an invalid number.'))
is_valid = False
continue
if prof_value > Decimal('0.00'):
try:
refund = prov.new_refund_control_form_process(self.request, prof_value, self.order)
except ValidationError as e:
for err in e:
messages.error(self.request, err)
is_valid = False
continue
if refund:
refund_selected += refund.amount
refund.comment = comment
refund.source = OrderRefund.REFUND_SOURCE_ADMIN
refunds.append(refund)
for p in payments:
value = self.request.POST.get('refund-{}'.format(p.pk), '0') or '0'
value = formats.sanitize_separators(value)
try:
value = Decimal(value)
except (DecimalException, TypeError):
messages.error(self.request, _('You entered an invalid number.'))
is_valid = False
else:
if value == 0:
continue
elif value > p.available_amount:
messages.error(self.request, _('You can not refund more than the amount of a '
'payment that is not yet refunded.'))
is_valid = False
break
elif value != p.amount and not p.partial_refund_possible:
messages.error(self.request, _('You selected a partial refund for a payment method that '
'only supports full refunds.'))
is_valid = False
break
elif (p.partial_refund_possible or p.full_refund_possible) and value > 0:
refund_selected += value
refunds.append(OrderRefund(
order=self.order,
payment=p,
source=OrderRefund.REFUND_SOURCE_ADMIN,
state=OrderRefund.REFUND_STATE_CREATED,
amount=value,
comment=comment,
provider=p.provider
))
any_success = False
if refund_selected == full_refund and is_valid:
for r in refunds:
r.save()
self.order.log_action('pretix.event.order.refund.created', {
'local_id': r.local_id,
'provider': r.provider,
}, user=self.request.user)
if r.provider != "manual":
try:
r.payment_provider.execute_refund(r)
except PaymentException as e:
r.state = OrderRefund.REFUND_STATE_FAILED
r.save()
messages.error(self.request, _('One of the refunds failed to be processed. You should '
'retry to refund in a different way. The error message '
'was: {}').format(str(e)))
else:
any_success = True
if r.state == OrderRefund.REFUND_STATE_DONE:
messages.success(self.request, _('A refund of {} has been processed.').format(
money_filter(r.amount, self.request.event.currency)
))
elif r.state == OrderRefund.REFUND_STATE_CREATED:
messages.info(self.request, _('A refund of {} has been saved, but not yet '
'fully executed. You can mark it as complete '
'below.').format(
money_filter(r.amount, self.request.event.currency)
))
else:
any_success = True
if r.state == OrderRefund.REFUND_STATE_DONE:
self.order.log_action('pretix.event.order.refund.done', {
'local_id': r.local_id,
'provider': r.provider,
}, user=self.request.user)
if any_success:
if self.start_form.cleaned_data.get('action') == 'mark_refunded':
if self.order.cancel_allowed():
mark_order_refunded(self.order, user=self.request.user)
elif self.start_form.cleaned_data.get('action') == 'mark_pending':
if not (self.order.status == Order.STATUS_PAID and self.order.pending_sum <= 0):
self.order.status = Order.STATUS_PENDING
self.order.set_expires(
now(),
self.order.event.subevents.filter(
id__in=self.order.positions.values_list('subevent_id', flat=True))
)
self.order.save(update_fields=['status', 'expires'])
if giftcard_value and self.order.email:
messages.success(self.request, _('A new gift card was created. You can now send the user their '
'gift card code.'))
with language(self.order.locale, self.request.event.settings.region):
return redirect(reverse('control:event.order.sendmail', kwargs={
'event': self.request.event.slug,
'organizer': self.request.event.organizer.slug,
'code': self.order.code
}) + '?' + urlencode({
'subject': gettext('Your gift card code'),
'message': gettext(
'Hello,\n\nwe have refunded you {amount} for your order.\n\nYou can use the gift '
'card code {giftcard} to pay for future ticket purchases in our shop.\n\n'
'Your {event} team'
).format(
event="{event}",
amount=money_filter(giftcard_value, self.request.event.currency),
giftcard=giftcard.secret,
)
}))
return redirect(self.get_order_url())
else:
messages.error(self.request, _('The refunds you selected do not match the selected total refund '
'amount.'))
r = self.perform_refund(comment, full_refund, payments)
if r:
return r
new_refunds = []
for identifier, prov in self.request.event.get_payment_providers().items():
@@ -1376,9 +1136,264 @@ class OrderRefundView(OrderView):
self.request.POST.get('start-partial_amount') if self.request.method == 'POST'
else self.request.GET.get('start-partial_amount')
),
'start_form': self.start_form
'start_form': self.start_form,
'last_known_refund_id': self.order.refunds.aggregate(m=Max("id"))["m"] or 0,
})
@transaction.atomic()
def perform_refund(self, comment, full_refund, payments):
order = Order.objects.select_for_update(of=OF_SELF).get(pk=self.order.pk)
if self.request.POST.get("last_known_refund_id", "0") != str(self.order.refunds.aggregate(m=Max("id"))["m"] or 0):
messages.error(self.request, _('The refund was prevented due to a refund already being processed at the '
'same time. Please have a look at the order details and check if your '
'refund is still necessary.'))
return redirect(self.get_order_url())
refund_selected = Decimal('0.00')
refunds = []
is_valid = True
manual_value = self.request.POST.get('refund-manual', '0') or '0'
manual_value = formats.sanitize_separators(manual_value)
try:
manual_value = Decimal(manual_value)
except (DecimalException, TypeError):
messages.error(self.request, _('You entered an invalid number.'))
is_valid = False
else:
refund_selected += manual_value
if manual_value:
refunds.append(OrderRefund(
order=order,
payment=None,
source=OrderRefund.REFUND_SOURCE_ADMIN,
state=(
OrderRefund.REFUND_STATE_DONE
if self.request.POST.get('manual_state') == 'done'
else OrderRefund.REFUND_STATE_CREATED
),
execution_date=(
now()
if self.request.POST.get('manual_state') == 'done'
else None
),
amount=manual_value,
comment=comment,
provider='manual'
))
giftcard_value = self.request.POST.get('refund-new-giftcard', '0') or '0'
giftcard_value = formats.sanitize_separators(giftcard_value)
try:
giftcard_value = Decimal(giftcard_value)
except (DecimalException, TypeError):
messages.error(self.request, _('You entered an invalid number.'))
is_valid = False
else:
if giftcard_value:
refund_selected += giftcard_value
if self.request.POST.get('giftcard-expires'):
try:
expires = forms.DateField().to_python(self.request.POST.get('giftcard-expires'))
expires = make_aware(datetime.combine(
expires,
time(hour=23, minute=59, second=59)
), self.request.event.timezone)
except ValidationError as e:
messages.error(self.request, e.message)
is_valid = False
else:
expires = None
giftcard = self.request.organizer.issued_gift_cards.create(
expires=expires,
currency=self.request.event.currency,
testmode=order.testmode
)
giftcard.log_action('pretix.giftcards.created', user=self.request.user, data={})
refunds.append(OrderRefund(
order=order,
payment=None,
source=OrderRefund.REFUND_SOURCE_ADMIN,
state=OrderRefund.REFUND_STATE_CREATED,
execution_date=now(),
amount=giftcard_value,
provider='giftcard',
comment=comment,
info=json.dumps({
'gift_card': giftcard.pk
})
))
offsetting_value = self.request.POST.get('refund-offsetting', '0') or '0'
offsetting_value = formats.sanitize_separators(offsetting_value)
try:
offsetting_value = Decimal(offsetting_value)
except (DecimalException, TypeError):
messages.error(self.request, _('You entered an invalid number.'))
is_valid = False
else:
if offsetting_value:
refund_selected += offsetting_value
try:
offset_order = Order.objects.get(code=self.request.POST.get('order-offsetting'),
event__organizer=self.request.organizer)
except Order.DoesNotExist:
messages.error(self.request, _('You entered an order that could not be found.'))
is_valid = False
else:
if offset_order.event.currency != self.request.event.currency:
messages.error(self.request, _('You entered an order in an event with a different currency.'))
is_valid = False
refunds.append(OrderRefund(
order=order,
payment=None,
source=OrderRefund.REFUND_SOURCE_ADMIN,
state=OrderRefund.REFUND_STATE_DONE,
execution_date=now(),
amount=offsetting_value,
provider='offsetting',
comment=comment,
info=json.dumps({
'orders': [offset_order.code]
})
))
for identifier, prov in self.request.event.get_payment_providers().items():
prof_value = self.request.POST.get(f'newrefund-{identifier}', '0') or '0'
prof_value = formats.sanitize_separators(prof_value)
try:
prof_value = Decimal(prof_value)
except (DecimalException, TypeError):
messages.error(self.request, _('You entered an invalid number.'))
is_valid = False
continue
if prof_value > Decimal('0.00'):
try:
refund = prov.new_refund_control_form_process(self.request, prof_value, order)
except ValidationError as e:
for err in e:
messages.error(self.request, err)
is_valid = False
continue
if refund:
refund_selected += refund.amount
refund.comment = comment
refund.source = OrderRefund.REFUND_SOURCE_ADMIN
refunds.append(refund)
for p in payments:
value = self.request.POST.get('refund-{}'.format(p.pk), '0') or '0'
value = formats.sanitize_separators(value)
try:
value = Decimal(value)
except (DecimalException, TypeError):
messages.error(self.request, _('You entered an invalid number.'))
is_valid = False
else:
if value == 0:
continue
elif value > p.available_amount:
messages.error(self.request, _('You can not refund more than the amount of a '
'payment that is not yet refunded.'))
is_valid = False
break
elif value != p.amount and not p.partial_refund_possible:
messages.error(self.request, _('You selected a partial refund for a payment method that '
'only supports full refunds.'))
is_valid = False
break
elif (p.partial_refund_possible or p.full_refund_possible) and value > 0:
refund_selected += value
refunds.append(OrderRefund(
order=order,
payment=p,
source=OrderRefund.REFUND_SOURCE_ADMIN,
state=OrderRefund.REFUND_STATE_CREATED,
amount=value,
comment=comment,
provider=p.provider
))
any_success = False
if refund_selected == full_refund and is_valid:
for r in refunds:
r.save()
order.log_action('pretix.event.order.refund.created', {
'local_id': r.local_id,
'provider': r.provider,
}, user=self.request.user)
if r.provider != "manual":
try:
r.payment_provider.execute_refund(r)
except PaymentException as e:
r.state = OrderRefund.REFUND_STATE_FAILED
r.save()
messages.error(self.request, _('One of the refunds failed to be processed. You should '
'retry to refund in a different way. The error message '
'was: {}').format(str(e)))
else:
any_success = True
if r.state == OrderRefund.REFUND_STATE_DONE:
messages.success(self.request, _('A refund of {} has been processed.').format(
money_filter(r.amount, self.request.event.currency)
))
elif r.state == OrderRefund.REFUND_STATE_CREATED:
messages.info(self.request, _('A refund of {} has been saved, but not yet '
'fully executed. You can mark it as complete '
'below.').format(
money_filter(r.amount, self.request.event.currency)
))
else:
any_success = True
if r.state == OrderRefund.REFUND_STATE_DONE:
order.log_action('pretix.event.order.refund.done', {
'local_id': r.local_id,
'provider': r.provider,
}, user=self.request.user)
if any_success:
if self.start_form.cleaned_data.get('action') == 'mark_refunded':
if order.cancel_allowed():
mark_order_refunded(order, user=self.request.user)
elif self.start_form.cleaned_data.get('action') == 'mark_pending':
if not (order.status == Order.STATUS_PAID and self.order.pending_sum <= 0):
order.status = Order.STATUS_PENDING
order.set_expires(
now(),
order.event.subevents.filter(
id__in=order.positions.values_list('subevent_id', flat=True))
)
order.save(update_fields=['status', 'expires'])
if giftcard_value and order.email:
messages.success(self.request, _('A new gift card was created. You can now send the user their '
'gift card code.'))
with language(order.locale, self.request.event.settings.region):
return redirect(reverse('control:event.order.sendmail', kwargs={
'event': self.request.event.slug,
'organizer': self.request.event.organizer.slug,
'code': order.code
}) + '?' + urlencode({
'subject': gettext('Your gift card code'),
'message': gettext(
'Hello,\n\nwe have refunded you {amount} for your order.\n\nYou can use the gift '
'card code {giftcard} to pay for future ticket purchases in our shop.\n\n'
'Your {event} team'
).format(
event="{event}",
amount=money_filter(giftcard_value, self.request.event.currency),
giftcard=giftcard.secret,
)
}))
return redirect(self.get_order_url())
else:
messages.error(self.request, _('The refunds you selected do not match the selected total refund '
'amount.'))
def post(self, *args, **kwargs):
if self.start_form.is_valid():
return self.choose_form()
File diff suppressed because it is too large Load Diff
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-04-23 12:41+0000\n"
"POT-Creation-Date: 2024-05-08 13:19+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -627,23 +627,23 @@ msgstr ""
msgid "Selected only"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:794
#: pretix/static/pretixcontrol/js/ui/main.js:828
msgid "Enter page number between 1 and %(max)s."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:797
#: pretix/static/pretixcontrol/js/ui/main.js:831
msgid "Invalid page number."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:955
#: pretix/static/pretixcontrol/js/ui/main.js:989
msgid "Use a different name internally"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:995
#: pretix/static/pretixcontrol/js/ui/main.js:1029
msgid "Click to close"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1070
#: pretix/static/pretixcontrol/js/ui/main.js:1104
msgid "You have unsaved changes!"
msgstr ""
File diff suppressed because it is too large Load Diff
+6 -6
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-04-23 12:41+0000\n"
"POT-Creation-Date: 2024-05-08 13:19+0000\n"
"PO-Revision-Date: 2021-09-15 11:22+0000\n"
"Last-Translator: Mohamed Tawfiq <mtawfiq@wafyapp.com>\n"
"Language-Team: Arabic <https://translate.pretix.eu/projects/pretix/pretix-js/"
@@ -657,23 +657,23 @@ msgstr "لا شيء"
msgid "Selected only"
msgstr "المختارة فقط"
#: pretix/static/pretixcontrol/js/ui/main.js:794
#: pretix/static/pretixcontrol/js/ui/main.js:828
msgid "Enter page number between 1 and %(max)s."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:797
#: pretix/static/pretixcontrol/js/ui/main.js:831
msgid "Invalid page number."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:955
#: pretix/static/pretixcontrol/js/ui/main.js:989
msgid "Use a different name internally"
msgstr "قم باستخدم اسم مختلف داخليا"
#: pretix/static/pretixcontrol/js/ui/main.js:995
#: pretix/static/pretixcontrol/js/ui/main.js:1029
msgid "Click to close"
msgstr "اضغط لاغلاق الصفحة"
#: pretix/static/pretixcontrol/js/ui/main.js:1070
#: pretix/static/pretixcontrol/js/ui/main.js:1104
msgid "You have unsaved changes!"
msgstr "لم تقم بحفظ التعديلات!"
File diff suppressed because it is too large Load Diff
+6 -6
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-04-23 12:41+0000\n"
"POT-Creation-Date: 2024-05-08 13:19+0000\n"
"PO-Revision-Date: 2020-12-19 07:00+0000\n"
"Last-Translator: albert <albert.serra.monner@gmail.com>\n"
"Language-Team: Catalan <https://translate.pretix.eu/projects/pretix/pretix-"
@@ -628,23 +628,23 @@ msgstr ""
msgid "Selected only"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:794
#: pretix/static/pretixcontrol/js/ui/main.js:828
msgid "Enter page number between 1 and %(max)s."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:797
#: pretix/static/pretixcontrol/js/ui/main.js:831
msgid "Invalid page number."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:955
#: pretix/static/pretixcontrol/js/ui/main.js:989
msgid "Use a different name internally"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:995
#: pretix/static/pretixcontrol/js/ui/main.js:1029
msgid "Click to close"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1070
#: pretix/static/pretixcontrol/js/ui/main.js:1104
msgid "You have unsaved changes!"
msgstr ""
File diff suppressed because it is too large Load Diff
+6 -6
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-04-23 12:41+0000\n"
"POT-Creation-Date: 2024-05-08 13:19+0000\n"
"PO-Revision-Date: 2023-09-15 06:00+0000\n"
"Last-Translator: Michael <michael.happl@gmx.at>\n"
"Language-Team: Czech <https://translate.pretix.eu/projects/pretix/pretix-js/"
@@ -651,23 +651,23 @@ msgstr "Žádný"
msgid "Selected only"
msgstr "Pouze vybrané"
#: pretix/static/pretixcontrol/js/ui/main.js:794
#: pretix/static/pretixcontrol/js/ui/main.js:828
msgid "Enter page number between 1 and %(max)s."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:797
#: pretix/static/pretixcontrol/js/ui/main.js:831
msgid "Invalid page number."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:955
#: pretix/static/pretixcontrol/js/ui/main.js:989
msgid "Use a different name internally"
msgstr "Interně používat jiný název"
#: pretix/static/pretixcontrol/js/ui/main.js:995
#: pretix/static/pretixcontrol/js/ui/main.js:1029
msgid "Click to close"
msgstr "Kliknutím zavřete"
#: pretix/static/pretixcontrol/js/ui/main.js:1070
#: pretix/static/pretixcontrol/js/ui/main.js:1104
msgid "You have unsaved changes!"
msgstr "Máte neuložené změny!"
File diff suppressed because it is too large Load Diff
+6 -6
View File
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-04-23 12:41+0000\n"
"POT-Creation-Date: 2024-05-08 13:19+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -628,23 +628,23 @@ msgstr ""
msgid "Selected only"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:794
#: pretix/static/pretixcontrol/js/ui/main.js:828
msgid "Enter page number between 1 and %(max)s."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:797
#: pretix/static/pretixcontrol/js/ui/main.js:831
msgid "Invalid page number."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:955
#: pretix/static/pretixcontrol/js/ui/main.js:989
msgid "Use a different name internally"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:995
#: pretix/static/pretixcontrol/js/ui/main.js:1029
msgid "Click to close"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1070
#: pretix/static/pretixcontrol/js/ui/main.js:1104
msgid "You have unsaved changes!"
msgstr ""
File diff suppressed because it is too large Load Diff
+6 -6
View File
@@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-04-23 12:41+0000\n"
"POT-Creation-Date: 2024-05-08 13:19+0000\n"
"PO-Revision-Date: 2022-12-01 17:00+0000\n"
"Last-Translator: Mie Frydensbjerg <mif@aarhus.dk>\n"
"Language-Team: Danish <https://translate.pretix.eu/projects/pretix/pretix-js/"
@@ -671,23 +671,23 @@ msgstr "Ingen"
msgid "Selected only"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:794
#: pretix/static/pretixcontrol/js/ui/main.js:828
msgid "Enter page number between 1 and %(max)s."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:797
#: pretix/static/pretixcontrol/js/ui/main.js:831
msgid "Invalid page number."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:955
#: pretix/static/pretixcontrol/js/ui/main.js:989
msgid "Use a different name internally"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:995
#: pretix/static/pretixcontrol/js/ui/main.js:1029
msgid "Click to close"
msgstr "Klik for at lukke"
#: pretix/static/pretixcontrol/js/ui/main.js:1070
#: pretix/static/pretixcontrol/js/ui/main.js:1104
msgid "You have unsaved changes!"
msgstr "Du har ændringer, der ikke er gemt!"
File diff suppressed because it is too large Load Diff
+6 -6
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-04-23 12:41+0000\n"
"POT-Creation-Date: 2024-05-08 13:19+0000\n"
"PO-Revision-Date: 2024-03-15 18:00+0000\n"
"Last-Translator: Raphael Michel <michel@rami.io>\n"
"Language-Team: German <https://translate.pretix.eu/projects/pretix/pretix-js/"
@@ -649,23 +649,23 @@ msgstr "Keine"
msgid "Selected only"
msgstr "Nur ausgewählte"
#: pretix/static/pretixcontrol/js/ui/main.js:794
#: pretix/static/pretixcontrol/js/ui/main.js:828
msgid "Enter page number between 1 and %(max)s."
msgstr "Geben Sie eine Seitenzahl zwischen 1 und %(max)s ein."
#: pretix/static/pretixcontrol/js/ui/main.js:797
#: pretix/static/pretixcontrol/js/ui/main.js:831
msgid "Invalid page number."
msgstr "Ungültige Seitenzahl."
#: pretix/static/pretixcontrol/js/ui/main.js:955
#: pretix/static/pretixcontrol/js/ui/main.js:989
msgid "Use a different name internally"
msgstr "Intern einen anderen Namen verwenden"
#: pretix/static/pretixcontrol/js/ui/main.js:995
#: pretix/static/pretixcontrol/js/ui/main.js:1029
msgid "Click to close"
msgstr "Klicken zum Schließen"
#: pretix/static/pretixcontrol/js/ui/main.js:1070
#: pretix/static/pretixcontrol/js/ui/main.js:1104
msgid "You have unsaved changes!"
msgstr "Sie haben ungespeicherte Änderungen!"
+2
View File
@@ -33,6 +33,7 @@ Backend
Badge
Badges
Bancontact
BankID
Banking
barcodes
Bcc
@@ -301,6 +302,7 @@ Strg
Stripe
Stripes
Strong
Swish
systemweiten
Tab
tag
File diff suppressed because it is too large Load Diff
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-04-23 12:41+0000\n"
"POT-Creation-Date: 2024-05-08 13:19+0000\n"
"PO-Revision-Date: 2024-03-15 18:00+0000\n"
"Last-Translator: Raphael Michel <michel@rami.io>\n"
"Language-Team: German (informal) <https://translate.pretix.eu/projects/"
@@ -648,23 +648,23 @@ msgstr "Keine"
msgid "Selected only"
msgstr "Nur ausgewählte"
#: pretix/static/pretixcontrol/js/ui/main.js:794
#: pretix/static/pretixcontrol/js/ui/main.js:828
msgid "Enter page number between 1 and %(max)s."
msgstr "Gib eine Seitenzahl zwischen 1 und %(max)s ein."
#: pretix/static/pretixcontrol/js/ui/main.js:797
#: pretix/static/pretixcontrol/js/ui/main.js:831
msgid "Invalid page number."
msgstr "Ungültige Seitenzahl."
#: pretix/static/pretixcontrol/js/ui/main.js:955
#: pretix/static/pretixcontrol/js/ui/main.js:989
msgid "Use a different name internally"
msgstr "Intern einen anderen Namen verwenden"
#: pretix/static/pretixcontrol/js/ui/main.js:995
#: pretix/static/pretixcontrol/js/ui/main.js:1029
msgid "Click to close"
msgstr "Klicken zum Schließen"
#: pretix/static/pretixcontrol/js/ui/main.js:1070
#: pretix/static/pretixcontrol/js/ui/main.js:1104
msgid "You have unsaved changes!"
msgstr "Du hast ungespeicherte Änderungen!"
@@ -33,6 +33,7 @@ Backend
Badge
Badges
Bancontact
BankID
Banking
barcodes
Bcc
@@ -301,6 +302,7 @@ Strg
Stripe
Stripes
Strong
Swish
systemweiten
Tab
tag
+1995 -1854
View File
File diff suppressed because it is too large Load Diff
+6 -6
View File
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-04-26 09:26+0000\n"
"POT-Creation-Date: 2024-05-24 08:47+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -627,23 +627,23 @@ msgstr ""
msgid "Selected only"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:794
#: pretix/static/pretixcontrol/js/ui/main.js:828
msgid "Enter page number between 1 and %(max)s."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:797
#: pretix/static/pretixcontrol/js/ui/main.js:831
msgid "Invalid page number."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:955
#: pretix/static/pretixcontrol/js/ui/main.js:989
msgid "Use a different name internally"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:995
#: pretix/static/pretixcontrol/js/ui/main.js:1029
msgid "Click to close"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1070
#: pretix/static/pretixcontrol/js/ui/main.js:1104
msgid "You have unsaved changes!"
msgstr ""
File diff suppressed because it is too large Load Diff
+6 -6
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-04-23 12:41+0000\n"
"POT-Creation-Date: 2024-05-08 13:19+0000\n"
"PO-Revision-Date: 2019-10-03 19:00+0000\n"
"Last-Translator: Chris Spy <chrispiropoulou@hotmail.com>\n"
"Language-Team: Greek <https://translate.pretix.eu/projects/pretix/pretix-js/"
@@ -687,23 +687,23 @@ msgstr "Κανένας"
msgid "Selected only"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:794
#: pretix/static/pretixcontrol/js/ui/main.js:828
msgid "Enter page number between 1 and %(max)s."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:797
#: pretix/static/pretixcontrol/js/ui/main.js:831
msgid "Invalid page number."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:955
#: pretix/static/pretixcontrol/js/ui/main.js:989
msgid "Use a different name internally"
msgstr "Χρησιμοποιήστε διαφορετικό όνομα εσωτερικά"
#: pretix/static/pretixcontrol/js/ui/main.js:995
#: pretix/static/pretixcontrol/js/ui/main.js:1029
msgid "Click to close"
msgstr "Κάντε κλικ για να κλείσετε"
#: pretix/static/pretixcontrol/js/ui/main.js:1070
#: pretix/static/pretixcontrol/js/ui/main.js:1104
msgid "You have unsaved changes!"
msgstr ""
File diff suppressed because it is too large Load Diff
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-04-23 12:41+0000\n"
"POT-Creation-Date: 2024-05-08 13:19+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -627,23 +627,23 @@ msgstr ""
msgid "Selected only"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:794
#: pretix/static/pretixcontrol/js/ui/main.js:828
msgid "Enter page number between 1 and %(max)s."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:797
#: pretix/static/pretixcontrol/js/ui/main.js:831
msgid "Invalid page number."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:955
#: pretix/static/pretixcontrol/js/ui/main.js:989
msgid "Use a different name internally"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:995
#: pretix/static/pretixcontrol/js/ui/main.js:1029
msgid "Click to close"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1070
#: pretix/static/pretixcontrol/js/ui/main.js:1104
msgid "You have unsaved changes!"
msgstr ""
File diff suppressed because it is too large Load Diff
+6 -6
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-04-23 12:41+0000\n"
"POT-Creation-Date: 2024-05-08 13:19+0000\n"
"PO-Revision-Date: 2023-11-07 14:00+0000\n"
"Last-Translator: Zona Vip <contacto@zonavip.mx>\n"
"Language-Team: Spanish <https://translate.pretix.eu/projects/pretix/pretix-"
@@ -657,23 +657,23 @@ msgstr "Ninguno"
msgid "Selected only"
msgstr "Solamente seleccionados"
#: pretix/static/pretixcontrol/js/ui/main.js:794
#: pretix/static/pretixcontrol/js/ui/main.js:828
msgid "Enter page number between 1 and %(max)s."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:797
#: pretix/static/pretixcontrol/js/ui/main.js:831
msgid "Invalid page number."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:955
#: pretix/static/pretixcontrol/js/ui/main.js:989
msgid "Use a different name internally"
msgstr "Usar un nombre diferente internamente"
#: pretix/static/pretixcontrol/js/ui/main.js:995
#: pretix/static/pretixcontrol/js/ui/main.js:1029
msgid "Click to close"
msgstr "Click para cerrar"
#: pretix/static/pretixcontrol/js/ui/main.js:1070
#: pretix/static/pretixcontrol/js/ui/main.js:1104
msgid "You have unsaved changes!"
msgstr "¡Tienes cambios sin guardar!"
File diff suppressed because it is too large Load Diff
+6 -6
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-04-23 12:41+0000\n"
"POT-Creation-Date: 2024-05-08 13:19+0000\n"
"PO-Revision-Date: 2021-11-10 05:00+0000\n"
"Last-Translator: Jaakko Rinta-Filppula <jaakko@r-f.fi>\n"
"Language-Team: Finnish <https://translate.pretix.eu/projects/pretix/pretix-"
@@ -652,23 +652,23 @@ msgstr ""
msgid "Selected only"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:794
#: pretix/static/pretixcontrol/js/ui/main.js:828
msgid "Enter page number between 1 and %(max)s."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:797
#: pretix/static/pretixcontrol/js/ui/main.js:831
msgid "Invalid page number."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:955
#: pretix/static/pretixcontrol/js/ui/main.js:989
msgid "Use a different name internally"
msgstr "Käytä toista nimeä sisäisesti"
#: pretix/static/pretixcontrol/js/ui/main.js:995
#: pretix/static/pretixcontrol/js/ui/main.js:1029
msgid "Click to close"
msgstr "Sulje klikkaamalla"
#: pretix/static/pretixcontrol/js/ui/main.js:1070
#: pretix/static/pretixcontrol/js/ui/main.js:1104
msgid "You have unsaved changes!"
msgstr "Sinulla on tallentamattomia muutoksia!"
File diff suppressed because it is too large Load Diff
+6 -6
View File
@@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: French\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-04-23 12:41+0000\n"
"POT-Creation-Date: 2024-05-08 13:19+0000\n"
"PO-Revision-Date: 2023-09-11 10:00+0000\n"
"Last-Translator: Ronan LE MEILLAT <ronan.le_meillat@highcanfly.club>\n"
"Language-Team: French <https://translate.pretix.eu/projects/pretix/pretix-js/"
@@ -656,23 +656,23 @@ msgstr "Aucun"
msgid "Selected only"
msgstr "Seuls les sélectionnés"
#: pretix/static/pretixcontrol/js/ui/main.js:794
#: pretix/static/pretixcontrol/js/ui/main.js:828
msgid "Enter page number between 1 and %(max)s."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:797
#: pretix/static/pretixcontrol/js/ui/main.js:831
msgid "Invalid page number."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:955
#: pretix/static/pretixcontrol/js/ui/main.js:989
msgid "Use a different name internally"
msgstr "Utiliser un nom différent en interne"
#: pretix/static/pretixcontrol/js/ui/main.js:995
#: pretix/static/pretixcontrol/js/ui/main.js:1029
msgid "Click to close"
msgstr "Cliquez pour fermer"
#: pretix/static/pretixcontrol/js/ui/main.js:1070
#: pretix/static/pretixcontrol/js/ui/main.js:1104
msgid "You have unsaved changes!"
msgstr "Vous avez des modifications non sauvegardées !"
File diff suppressed because it is too large Load Diff
+6 -6
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-04-23 12:41+0000\n"
"POT-Creation-Date: 2024-05-08 13:19+0000\n"
"PO-Revision-Date: 2022-02-22 22:00+0000\n"
"Last-Translator: Ismael Menéndez Fernández <ismael.menendez@balidea.com>\n"
"Language-Team: Galician <https://translate.pretix.eu/projects/pretix/pretix-"
@@ -659,23 +659,23 @@ msgstr "Ningún"
msgid "Selected only"
msgstr "Soamente seleccionados"
#: pretix/static/pretixcontrol/js/ui/main.js:794
#: pretix/static/pretixcontrol/js/ui/main.js:828
msgid "Enter page number between 1 and %(max)s."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:797
#: pretix/static/pretixcontrol/js/ui/main.js:831
msgid "Invalid page number."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:955
#: pretix/static/pretixcontrol/js/ui/main.js:989
msgid "Use a different name internally"
msgstr "Usar un nome diferente internamente"
#: pretix/static/pretixcontrol/js/ui/main.js:995
#: pretix/static/pretixcontrol/js/ui/main.js:1029
msgid "Click to close"
msgstr "Click para cerrar"
#: pretix/static/pretixcontrol/js/ui/main.js:1070
#: pretix/static/pretixcontrol/js/ui/main.js:1104
msgid "You have unsaved changes!"
msgstr "Tes cambios sen gardar!"
File diff suppressed because it is too large Load Diff
+6 -6
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-04-23 12:41+0000\n"
"POT-Creation-Date: 2024-05-08 13:19+0000\n"
"PO-Revision-Date: 2021-09-24 13:54+0000\n"
"Last-Translator: ofirtro <ofir.tro@gmail.com>\n"
"Language-Team: Hebrew <https://translate.pretix.eu/projects/pretix/pretix-js/"
@@ -635,23 +635,23 @@ msgstr ""
msgid "Selected only"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:794
#: pretix/static/pretixcontrol/js/ui/main.js:828
msgid "Enter page number between 1 and %(max)s."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:797
#: pretix/static/pretixcontrol/js/ui/main.js:831
msgid "Invalid page number."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:955
#: pretix/static/pretixcontrol/js/ui/main.js:989
msgid "Use a different name internally"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:995
#: pretix/static/pretixcontrol/js/ui/main.js:1029
msgid "Click to close"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1070
#: pretix/static/pretixcontrol/js/ui/main.js:1104
msgid "You have unsaved changes!"
msgstr ""
File diff suppressed because it is too large Load Diff
+6 -6
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-04-23 12:41+0000\n"
"POT-Creation-Date: 2024-05-08 13:19+0000\n"
"PO-Revision-Date: 2024-01-31 04:00+0000\n"
"Last-Translator: Pavle Ergović <pavleergovic@gmail.com>\n"
"Language-Team: Croatian <https://translate.pretix.eu/projects/pretix/pretix-"
@@ -629,23 +629,23 @@ msgstr ""
msgid "Selected only"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:794
#: pretix/static/pretixcontrol/js/ui/main.js:828
msgid "Enter page number between 1 and %(max)s."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:797
#: pretix/static/pretixcontrol/js/ui/main.js:831
msgid "Invalid page number."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:955
#: pretix/static/pretixcontrol/js/ui/main.js:989
msgid "Use a different name internally"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:995
#: pretix/static/pretixcontrol/js/ui/main.js:1029
msgid "Click to close"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1070
#: pretix/static/pretixcontrol/js/ui/main.js:1104
msgid "You have unsaved changes!"
msgstr ""
File diff suppressed because it is too large Load Diff
+6 -6
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-04-23 12:41+0000\n"
"POT-Creation-Date: 2024-05-08 13:19+0000\n"
"PO-Revision-Date: 2020-01-24 08:00+0000\n"
"Last-Translator: Prokaj Miklós <mixolid0@gmail.com>\n"
"Language-Team: Hungarian <https://translate.pretix.eu/projects/pretix/pretix-"
@@ -675,23 +675,23 @@ msgstr "Semmi"
msgid "Selected only"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:794
#: pretix/static/pretixcontrol/js/ui/main.js:828
msgid "Enter page number between 1 and %(max)s."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:797
#: pretix/static/pretixcontrol/js/ui/main.js:831
msgid "Invalid page number."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:955
#: pretix/static/pretixcontrol/js/ui/main.js:989
msgid "Use a different name internally"
msgstr "Használj másik nevet"
#: pretix/static/pretixcontrol/js/ui/main.js:995
#: pretix/static/pretixcontrol/js/ui/main.js:1029
msgid "Click to close"
msgstr "Bezárásért kattints"
#: pretix/static/pretixcontrol/js/ui/main.js:1070
#: pretix/static/pretixcontrol/js/ui/main.js:1104
msgid "You have unsaved changes!"
msgstr "Mentetlen változtatások!"
File diff suppressed because it is too large Load Diff
+6 -6
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-04-23 12:41+0000\n"
"POT-Creation-Date: 2024-05-08 13:19+0000\n"
"PO-Revision-Date: 2023-09-20 14:01+0000\n"
"Last-Translator: Mahdia Aliyy <mahdlyy.k@gmail.com>\n"
"Language-Team: Indonesian <https://translate.pretix.eu/projects/pretix/"
@@ -658,23 +658,23 @@ msgstr "Tidak ada"
msgid "Selected only"
msgstr "Hanya dipilih"
#: pretix/static/pretixcontrol/js/ui/main.js:794
#: pretix/static/pretixcontrol/js/ui/main.js:828
msgid "Enter page number between 1 and %(max)s."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:797
#: pretix/static/pretixcontrol/js/ui/main.js:831
msgid "Invalid page number."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:955
#: pretix/static/pretixcontrol/js/ui/main.js:989
msgid "Use a different name internally"
msgstr "Gunakan nama yang berbeda secara internal"
#: pretix/static/pretixcontrol/js/ui/main.js:995
#: pretix/static/pretixcontrol/js/ui/main.js:1029
msgid "Click to close"
msgstr "Klik untuk menutup"
#: pretix/static/pretixcontrol/js/ui/main.js:1070
#: pretix/static/pretixcontrol/js/ui/main.js:1104
msgid "You have unsaved changes!"
msgstr "Anda memiliki perubahan yang belum disimpan!"
File diff suppressed because it is too large Load Diff
+6 -6
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-04-23 12:41+0000\n"
"POT-Creation-Date: 2024-05-08 13:19+0000\n"
"PO-Revision-Date: 2023-05-18 01:00+0000\n"
"Last-Translator: M C <micasadmail@gmail.com>\n"
"Language-Team: Italian <https://translate.pretix.eu/projects/pretix/pretix-"
@@ -653,23 +653,23 @@ msgstr "Nessuno"
msgid "Selected only"
msgstr "Solo i selezionati"
#: pretix/static/pretixcontrol/js/ui/main.js:794
#: pretix/static/pretixcontrol/js/ui/main.js:828
msgid "Enter page number between 1 and %(max)s."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:797
#: pretix/static/pretixcontrol/js/ui/main.js:831
msgid "Invalid page number."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:955
#: pretix/static/pretixcontrol/js/ui/main.js:989
msgid "Use a different name internally"
msgstr "Utilizza un nome diverso internamente"
#: pretix/static/pretixcontrol/js/ui/main.js:995
#: pretix/static/pretixcontrol/js/ui/main.js:1029
msgid "Click to close"
msgstr "Clicca per chiudere"
#: pretix/static/pretixcontrol/js/ui/main.js:1070
#: pretix/static/pretixcontrol/js/ui/main.js:1104
msgid "You have unsaved changes!"
msgstr "Hai cambiamenti non salvati!"
File diff suppressed because it is too large Load Diff
+6 -6
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-04-23 12:41+0000\n"
"POT-Creation-Date: 2024-05-08 13:19+0000\n"
"PO-Revision-Date: 2022-03-15 00:00+0000\n"
"Last-Translator: Yuriko Matsunami <y.matsunami@enobyte.com>\n"
"Language-Team: Japanese <https://translate.pretix.eu/projects/pretix/pretix-"
@@ -655,23 +655,23 @@ msgstr "ない"
msgid "Selected only"
msgstr "選択したもののみ"
#: pretix/static/pretixcontrol/js/ui/main.js:794
#: pretix/static/pretixcontrol/js/ui/main.js:828
msgid "Enter page number between 1 and %(max)s."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:797
#: pretix/static/pretixcontrol/js/ui/main.js:831
msgid "Invalid page number."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:955
#: pretix/static/pretixcontrol/js/ui/main.js:989
msgid "Use a different name internally"
msgstr "内部で別の名前を使用してください"
#: pretix/static/pretixcontrol/js/ui/main.js:995
#: pretix/static/pretixcontrol/js/ui/main.js:1029
msgid "Click to close"
msgstr "クリックして閉じる"
#: pretix/static/pretixcontrol/js/ui/main.js:1070
#: pretix/static/pretixcontrol/js/ui/main.js:1104
msgid "You have unsaved changes!"
msgstr "保存されていない変更があります!"
File diff suppressed because it is too large Load Diff
+6 -6
View File
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-04-23 12:41+0000\n"
"POT-Creation-Date: 2024-05-08 13:19+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -627,23 +627,23 @@ msgstr ""
msgid "Selected only"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:794
#: pretix/static/pretixcontrol/js/ui/main.js:828
msgid "Enter page number between 1 and %(max)s."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:797
#: pretix/static/pretixcontrol/js/ui/main.js:831
msgid "Invalid page number."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:955
#: pretix/static/pretixcontrol/js/ui/main.js:989
msgid "Use a different name internally"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:995
#: pretix/static/pretixcontrol/js/ui/main.js:1029
msgid "Click to close"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1070
#: pretix/static/pretixcontrol/js/ui/main.js:1104
msgid "You have unsaved changes!"
msgstr ""
File diff suppressed because it is too large Load Diff
+6 -6
View File
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-04-23 12:41+0000\n"
"POT-Creation-Date: 2024-05-08 13:19+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -629,23 +629,23 @@ msgstr ""
msgid "Selected only"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:794
#: pretix/static/pretixcontrol/js/ui/main.js:828
msgid "Enter page number between 1 and %(max)s."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:797
#: pretix/static/pretixcontrol/js/ui/main.js:831
msgid "Invalid page number."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:955
#: pretix/static/pretixcontrol/js/ui/main.js:989
msgid "Use a different name internally"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:995
#: pretix/static/pretixcontrol/js/ui/main.js:1029
msgid "Click to close"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1070
#: pretix/static/pretixcontrol/js/ui/main.js:1104
msgid "You have unsaved changes!"
msgstr ""
File diff suppressed because it is too large Load Diff
+6 -6
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-04-23 12:41+0000\n"
"POT-Creation-Date: 2024-05-08 13:19+0000\n"
"PO-Revision-Date: 2022-04-06 03:00+0000\n"
"Last-Translator: Liga V <lerning_by_dreaming@gmx.de>\n"
"Language-Team: Latvian <https://translate.pretix.eu/projects/pretix/pretix-"
@@ -662,23 +662,23 @@ msgstr "Neviens"
msgid "Selected only"
msgstr "Tikai atzīmētos"
#: pretix/static/pretixcontrol/js/ui/main.js:794
#: pretix/static/pretixcontrol/js/ui/main.js:828
msgid "Enter page number between 1 and %(max)s."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:797
#: pretix/static/pretixcontrol/js/ui/main.js:831
msgid "Invalid page number."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:955
#: pretix/static/pretixcontrol/js/ui/main.js:989
msgid "Use a different name internally"
msgstr "Izmantojiet citu nosaukumu iekšēji"
#: pretix/static/pretixcontrol/js/ui/main.js:995
#: pretix/static/pretixcontrol/js/ui/main.js:1029
msgid "Click to close"
msgstr "Noklikšķiniet, lai aizvērtu"
#: pretix/static/pretixcontrol/js/ui/main.js:1070
#: pretix/static/pretixcontrol/js/ui/main.js:1104
msgid "You have unsaved changes!"
msgstr "Jums ir nesaglabātas izmaiņas!"
File diff suppressed because it is too large Load Diff
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-04-23 12:41+0000\n"
"POT-Creation-Date: 2024-05-08 13:19+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -627,23 +627,23 @@ msgstr ""
msgid "Selected only"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:794
#: pretix/static/pretixcontrol/js/ui/main.js:828
msgid "Enter page number between 1 and %(max)s."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:797
#: pretix/static/pretixcontrol/js/ui/main.js:831
msgid "Invalid page number."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:955
#: pretix/static/pretixcontrol/js/ui/main.js:989
msgid "Use a different name internally"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:995
#: pretix/static/pretixcontrol/js/ui/main.js:1029
msgid "Click to close"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1070
#: pretix/static/pretixcontrol/js/ui/main.js:1104
msgid "You have unsaved changes!"
msgstr ""
File diff suppressed because it is too large Load Diff
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-04-23 12:41+0000\n"
"POT-Creation-Date: 2024-05-08 13:19+0000\n"
"PO-Revision-Date: 2024-03-10 03:00+0000\n"
"Last-Translator: fyksen <fredrik@fyksen.me>\n"
"Language-Team: Norwegian Bokmål <https://translate.pretix.eu/projects/pretix/"
@@ -642,23 +642,23 @@ msgstr "Ingen"
msgid "Selected only"
msgstr "Kun valgte"
#: pretix/static/pretixcontrol/js/ui/main.js:794
#: pretix/static/pretixcontrol/js/ui/main.js:828
msgid "Enter page number between 1 and %(max)s."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:797
#: pretix/static/pretixcontrol/js/ui/main.js:831
msgid "Invalid page number."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:955
#: pretix/static/pretixcontrol/js/ui/main.js:989
msgid "Use a different name internally"
msgstr "Bruk et annet navn internt"
#: pretix/static/pretixcontrol/js/ui/main.js:995
#: pretix/static/pretixcontrol/js/ui/main.js:1029
msgid "Click to close"
msgstr "Klikk for å lukke"
#: pretix/static/pretixcontrol/js/ui/main.js:1070
#: pretix/static/pretixcontrol/js/ui/main.js:1104
msgid "You have unsaved changes!"
msgstr "Du har ikke-lagrede endringer!"
File diff suppressed because it is too large Load Diff
+6 -6
View File
@@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-04-23 12:41+0000\n"
"POT-Creation-Date: 2024-05-08 13:19+0000\n"
"PO-Revision-Date: 2023-11-14 23:00+0000\n"
"Last-Translator: Thomas Vranken <thvranken@gmail.com>\n"
"Language-Team: Dutch <https://translate.pretix.eu/projects/pretix/pretix-js/"
@@ -655,23 +655,23 @@ msgstr "Geen"
msgid "Selected only"
msgstr "Alleen geselecteerde"
#: pretix/static/pretixcontrol/js/ui/main.js:794
#: pretix/static/pretixcontrol/js/ui/main.js:828
msgid "Enter page number between 1 and %(max)s."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:797
#: pretix/static/pretixcontrol/js/ui/main.js:831
msgid "Invalid page number."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:955
#: pretix/static/pretixcontrol/js/ui/main.js:989
msgid "Use a different name internally"
msgstr "Gebruik intern een andere naam"
#: pretix/static/pretixcontrol/js/ui/main.js:995
#: pretix/static/pretixcontrol/js/ui/main.js:1029
msgid "Click to close"
msgstr "Klik om te sluiten"
#: pretix/static/pretixcontrol/js/ui/main.js:1070
#: pretix/static/pretixcontrol/js/ui/main.js:1104
msgid "You have unsaved changes!"
msgstr "U heeft nog niet opgeslagen wijzigingen!"
File diff suppressed because it is too large Load Diff
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-04-23 12:41+0000\n"
"POT-Creation-Date: 2024-05-08 13:19+0000\n"
"PO-Revision-Date: 2021-08-05 04:00+0000\n"
"Last-Translator: Maarten van den Berg <maartenberg1@gmail.com>\n"
"Language-Team: Dutch (informal) <https://translate.pretix.eu/projects/pretix/"
@@ -660,23 +660,23 @@ msgstr "Geen"
msgid "Selected only"
msgstr "Alleen geselecteerde"
#: pretix/static/pretixcontrol/js/ui/main.js:794
#: pretix/static/pretixcontrol/js/ui/main.js:828
msgid "Enter page number between 1 and %(max)s."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:797
#: pretix/static/pretixcontrol/js/ui/main.js:831
msgid "Invalid page number."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:955
#: pretix/static/pretixcontrol/js/ui/main.js:989
msgid "Use a different name internally"
msgstr "Gebruik intern een andere naam"
#: pretix/static/pretixcontrol/js/ui/main.js:995
#: pretix/static/pretixcontrol/js/ui/main.js:1029
msgid "Click to close"
msgstr "Klik om te sluiten"
#: pretix/static/pretixcontrol/js/ui/main.js:1070
#: pretix/static/pretixcontrol/js/ui/main.js:1104
msgid "You have unsaved changes!"
msgstr "Je hebt nog niet opgeslagen wijzigingen!"
File diff suppressed because it is too large Load Diff
+10 -10
View File
@@ -7,9 +7,9 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-04-23 12:41+0000\n"
"PO-Revision-Date: 2023-11-25 22:12+0000\n"
"Last-Translator: c0de-bender <code-bender@mailbox.org>\n"
"POT-Creation-Date: 2024-05-08 13:19+0000\n"
"PO-Revision-Date: 2024-05-07 22:00+0000\n"
"Last-Translator: Adam Kaput <adamkaput@gmail.com>\n"
"Language-Team: Polish <https://translate.pretix.eu/projects/pretix/pretix-js/"
"pl/>\n"
"Language: pl\n"
@@ -18,7 +18,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
"|| n%100>=20) ? 1 : 2;\n"
"X-Generator: Weblate 5.1.1\n"
"X-Generator: Weblate 5.4.3\n"
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
@@ -308,7 +308,7 @@ msgstr "Kod biletu jest niejednoznaczny na liście"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:65
msgid "Order not approved"
msgstr ""
msgstr "Zamówienie niezaakceptowane"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:66
msgid "Checked-in Tickets"
@@ -650,23 +650,23 @@ msgstr "Odznacz wszystko"
msgid "Selected only"
msgstr "Tylko wybrane"
#: pretix/static/pretixcontrol/js/ui/main.js:794
#: pretix/static/pretixcontrol/js/ui/main.js:828
msgid "Enter page number between 1 and %(max)s."
msgstr "Wprowadź numer strony między 1 a %(max)s."
#: pretix/static/pretixcontrol/js/ui/main.js:797
#: pretix/static/pretixcontrol/js/ui/main.js:831
msgid "Invalid page number."
msgstr "Niepoprawny numer strony."
#: pretix/static/pretixcontrol/js/ui/main.js:955
#: pretix/static/pretixcontrol/js/ui/main.js:989
msgid "Use a different name internally"
msgstr "Użyj innej nazwy wewnętrznie"
#: pretix/static/pretixcontrol/js/ui/main.js:995
#: pretix/static/pretixcontrol/js/ui/main.js:1029
msgid "Click to close"
msgstr "Zamknij"
#: pretix/static/pretixcontrol/js/ui/main.js:1070
#: pretix/static/pretixcontrol/js/ui/main.js:1104
msgid "You have unsaved changes!"
msgstr "Masz niezapisane zmiany!"
File diff suppressed because it is too large Load Diff
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-04-23 12:41+0000\n"
"POT-Creation-Date: 2024-05-08 13:19+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
@@ -627,23 +627,23 @@ msgstr ""
msgid "Selected only"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:794
#: pretix/static/pretixcontrol/js/ui/main.js:828
msgid "Enter page number between 1 and %(max)s."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:797
#: pretix/static/pretixcontrol/js/ui/main.js:831
msgid "Invalid page number."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:955
#: pretix/static/pretixcontrol/js/ui/main.js:989
msgid "Use a different name internally"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:995
#: pretix/static/pretixcontrol/js/ui/main.js:1029
msgid "Click to close"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1070
#: pretix/static/pretixcontrol/js/ui/main.js:1104
msgid "You have unsaved changes!"
msgstr ""
File diff suppressed because it is too large Load Diff
+6 -6
View File
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-04-23 12:41+0000\n"
"POT-Creation-Date: 2024-05-08 13:19+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -627,23 +627,23 @@ msgstr ""
msgid "Selected only"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:794
#: pretix/static/pretixcontrol/js/ui/main.js:828
msgid "Enter page number between 1 and %(max)s."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:797
#: pretix/static/pretixcontrol/js/ui/main.js:831
msgid "Invalid page number."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:955
#: pretix/static/pretixcontrol/js/ui/main.js:989
msgid "Use a different name internally"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:995
#: pretix/static/pretixcontrol/js/ui/main.js:1029
msgid "Click to close"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1070
#: pretix/static/pretixcontrol/js/ui/main.js:1104
msgid "You have unsaved changes!"
msgstr ""
File diff suppressed because it is too large Load Diff
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-04-23 12:41+0000\n"
"POT-Creation-Date: 2024-05-08 13:19+0000\n"
"PO-Revision-Date: 2019-03-19 09:00+0000\n"
"Last-Translator: Vitor Reis <vitor.reis7@gmail.com>\n"
"Language-Team: Portuguese (Brazil) <https://translate.pretix.eu/projects/"
@@ -686,23 +686,23 @@ msgstr "Nenhum"
msgid "Selected only"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:794
#: pretix/static/pretixcontrol/js/ui/main.js:828
msgid "Enter page number between 1 and %(max)s."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:797
#: pretix/static/pretixcontrol/js/ui/main.js:831
msgid "Invalid page number."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:955
#: pretix/static/pretixcontrol/js/ui/main.js:989
msgid "Use a different name internally"
msgstr "Use um nome diferente internamente"
#: pretix/static/pretixcontrol/js/ui/main.js:995
#: pretix/static/pretixcontrol/js/ui/main.js:1029
msgid "Click to close"
msgstr "Clique para fechar"
#: pretix/static/pretixcontrol/js/ui/main.js:1070
#: pretix/static/pretixcontrol/js/ui/main.js:1104
msgid "You have unsaved changes!"
msgstr ""
File diff suppressed because it is too large Load Diff
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-04-23 12:41+0000\n"
"POT-Creation-Date: 2024-05-08 13:19+0000\n"
"PO-Revision-Date: 2022-11-16 16:12+0000\n"
"Last-Translator: David Vaz <davidmgvaz@gmail.com>\n"
"Language-Team: Portuguese (Portugal) <https://translate.pretix.eu/projects/"
@@ -673,23 +673,23 @@ msgstr "Nada"
msgid "Selected only"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:794
#: pretix/static/pretixcontrol/js/ui/main.js:828
msgid "Enter page number between 1 and %(max)s."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:797
#: pretix/static/pretixcontrol/js/ui/main.js:831
msgid "Invalid page number."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:955
#: pretix/static/pretixcontrol/js/ui/main.js:989
msgid "Use a different name internally"
msgstr "Use um nome interno diferente"
#: pretix/static/pretixcontrol/js/ui/main.js:995
#: pretix/static/pretixcontrol/js/ui/main.js:1029
msgid "Click to close"
msgstr "Clique para fechar"
#: pretix/static/pretixcontrol/js/ui/main.js:1070
#: pretix/static/pretixcontrol/js/ui/main.js:1104
msgid "You have unsaved changes!"
msgstr "Tem alterações por guardar!"

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