Compare commits

...
Author SHA1 Message Date
Raphael Michel a18318bae1 Thumbnails: Store creation date 2022-11-21 18:23:23 +01:00
Raphael Michel b539f5e2f2 Fix image size validation in product form 2022-11-21 18:17:38 +01:00
Martin Gross a18eb3be70 Plugins: Fix check if a restricted plugin is really restricted 2022-11-21 16:25:34 +01:00
Raphael MichelandRaphael Michel ac59bbff5d Translations: Update German (informal) (de_Informal)
Currently translated at 100.0% (4902 of 4902 strings)

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

powered by weblate
2022-11-21 16:17:07 +01:00
Raphael MichelandRaphael Michel 69f3e938f2 Translations: Update German
Currently translated at 100.0% (4902 of 4902 strings)

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

powered by weblate
2022-11-21 16:17:07 +01:00
Raphael MichelandRaphael Michel a0c1903ce5 Translations: Update German (informal) (de_Informal)
Currently translated at 100.0% (4902 of 4902 strings)

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

powered by weblate
2022-11-21 16:17:07 +01:00
Raphael MichelandRaphael Michel 3c8b188352 Translations: Update German
Currently translated at 100.0% (4902 of 4902 strings)

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

powered by weblate
2022-11-21 16:17:07 +01:00
tlm06andRaphael Michel 76e3b39f8f Translations: Update Portuguese (Portugal)
Currently translated at 84.9% (4151 of 4888 strings)

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

powered by weblate
2022-11-21 16:17:07 +01:00
Raphael Michel 662e2cd116 Update po files
[CI skip]

Signed-off-by: Raphael Michel <michel@rami.io>
2022-11-21 15:52:18 +01:00
tlm06andRaphael Michel eeaa3bc2a9 Translations: Update Portuguese (Portugal)
Currently translated at 84.9% (4150 of 4888 strings)

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

powered by weblate
2022-11-21 15:48:18 +01:00
David VazandRaphael Michel bbe8247606 Translations: Update Portuguese (Portugal)
Currently translated at 84.9% (4150 of 4888 strings)

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

powered by weblate
2022-11-21 15:48:18 +01:00
tlm06andRaphael Michel 5c46c1d14f Translations: Update Portuguese (Portugal)
Currently translated at 84.2% (4119 of 4888 strings)

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

powered by weblate
2022-11-21 15:48:18 +01:00
David VazandRaphael Michel 651b676cfc Translations: Update Portuguese (Portugal)
Currently translated at 84.2% (4119 of 4888 strings)

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

powered by weblate
2022-11-21 15:48:18 +01:00
Raphael MichelandGitHub 5ee62c551e Group identical lines on invoice PDF (#2918) 2022-11-21 15:47:57 +01:00
Raphael Michel 50e79b51de Customer login: Don't chain next= calls to login page 2022-11-20 14:46:32 +01:00
Raphael Michel 6e24c20a7a Fix edge case in bundle price configuration 2022-11-20 14:20:40 +01:00
Raphael Michel 481a242054 GitHub actions: Fix missed package upgrade 2022-11-20 13:05:55 +01:00
Raphael Michel f923c2fed0 Fix price calculation of included add-ons in expired carts 2022-11-18 17:24:02 +01:00
Raphael Michel 228448b00f Bump libsass to 0.22 2022-11-18 16:45:29 +01:00
Raphael Michel 603345762a Bump sepaxml to 2.6.* 2022-11-18 16:45:29 +01:00
tlm06andRaphael Michel 1812a23860 Translations: Update Portuguese (Portugal)
Currently translated at 83.3% (4076 of 4888 strings)

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

powered by weblate
2022-11-18 16:44:07 +01:00
David VazandRaphael Michel 45374d0c94 Translations: Update Portuguese (Portugal)
Currently translated at 83.0% (4061 of 4888 strings)

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

powered by weblate
2022-11-18 16:44:07 +01:00
tlm06andRaphael Michel c5f823596e Translations: Update Portuguese (Portugal)
Currently translated at 83.0% (4061 of 4888 strings)

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

powered by weblate
2022-11-18 16:44:07 +01:00
David VazandRaphael Michel eebb0a3527 Translations: Update Portuguese (Portugal)
Currently translated at 83.0% (4061 of 4888 strings)

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

powered by weblate
2022-11-18 16:44:07 +01:00
tlm06andRaphael Michel bac1e8faf6 Translations: Update Portuguese (Portugal)
Currently translated at 82.7% (4046 of 4888 strings)

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

powered by weblate
2022-11-18 16:44:07 +01:00
tlm06andRaphael Michel 5cf7654099 Translations: Update Portuguese (Portugal)
Currently translated at 81.5% (3987 of 4888 strings)

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

powered by weblate
2022-11-18 16:44:07 +01:00
AlexandGitHub 988ef53972 GitHub Actions: Security hardening (#2882) 2022-11-18 16:32:05 +01:00
Raphael MichelandGitHub 36d20a45dd Sendmail: Fix inconsistent handling of addons and checkins (#2914) 2022-11-18 14:20:43 +01:00
Raphael MichelandGitHub 0691af7aa4 GitHub Actions: Pin ubuntu version and fix package versions (#2915) 2022-11-18 13:32:35 +01:00
Raphael Michel 6b5436b71a GitHub Actions: Don't rely on specific MariaDB client version 2022-11-18 13:08:38 +01:00
Raphael Michel a06a693c5c Widget: Fix markup for voucher explanation text 2022-11-17 18:29:15 +01:00
Raphael Michel 7b58ddbfde Don't use Django's redirect() for user-supplied paths 2022-11-17 11:46:03 +01:00
Raphael Michel f18fb02d0b Fix tests and docs for 62a6a1183 2022-11-16 17:18:54 +01:00
Raphael Michel 3a185b1cbc Bump django-formset-js-improved to 0.5.0.3 2022-11-16 17:17:09 +01:00
Raphael Michel ba2a9fbd93 Bump arabic-reshaper to 2.1.4 2022-11-16 17:17:09 +01:00
Raphael Michel a337cf8efa Fix rare crash in MembershipStep 2022-11-16 17:17:09 +01:00
David VazandRaphael Michel 616cc42b9c Translations: Update Portuguese (Portugal)
Currently translated at 64.1% (129 of 201 strings)

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

powered by weblate
2022-11-16 17:17:03 +01:00
David VazandRaphael Michel 08012c42f2 Translations: Update Portuguese (Portugal)
Currently translated at 80.8% (3954 of 4888 strings)

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

powered by weblate
2022-11-16 17:17:03 +01:00
David VazandRaphael Michel 08368684b0 Translations: Update Portuguese (Portugal)
Currently translated at 63.6% (128 of 201 strings)

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

powered by weblate
2022-11-16 17:17:03 +01:00
David VazandRaphael Michel 17200df0cd Translations: Update Portuguese (Portugal)
Currently translated at 80.4% (3933 of 4888 strings)

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

powered by weblate
2022-11-16 17:17:03 +01:00
tlm06andRaphael Michel 28d1bedfc4 Translations: Update Portuguese (Portugal)
Currently translated at 80.4% (3933 of 4888 strings)

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

powered by weblate
2022-11-16 17:17:03 +01:00
tlm06andRaphael Michel af90db9d1e Translations: Update Portuguese (Portugal)
Currently translated at 79.1% (3867 of 4888 strings)

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

powered by weblate
2022-11-16 17:17:03 +01:00
David VazandRaphael Michel 19c4089da9 Translations: Update Portuguese (Portugal)
Currently translated at 78.9% (3859 of 4888 strings)

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

powered by weblate
2022-11-16 17:17:03 +01:00
Alexander Mohan Morzeria-DavisandRaphael Michel 71723935e1 Translations: Update French
Currently translated at 47.0% (2300 of 4888 strings)

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

powered by weblate
2022-11-16 17:17:03 +01:00
David VazandRaphael Michel e2ad8f2f74 Translations: Update Portuguese (Portugal)
Currently translated at 63.6% (128 of 201 strings)

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

powered by weblate
2022-11-16 17:17:03 +01:00
David VazandRaphael Michel f8580a2789 Translations: Update Portuguese (Portugal)
Currently translated at 78.5% (3840 of 4888 strings)

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

powered by weblate
2022-11-16 17:17:03 +01:00
Raphael MichelandRaphael Michel cfeaa502a3 Translations: Update German (informal) (de_Informal)
Currently translated at 99.6% (4873 of 4888 strings)

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

powered by weblate
2022-11-16 17:17:03 +01:00
Raphael MichelandRaphael Michel 0ee8d6e9c3 Translations: Update German
Currently translated at 99.6% (4889 of 4904 strings)

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

powered by weblate
2022-11-16 17:17:03 +01:00
Raphael MichelandGitHub a0e5717f7d Allow to disable filter support for meta properties (#2901) 2022-11-16 17:12:37 +01:00
Raphael Michel 49097037da PPv2: Improve displaying errors 2022-11-16 11:50:29 +01:00
Raphael Michel 62a6a11836 Add refund details to API 2022-11-15 18:10:19 +01:00
Raphael Michel 3d82058269 Do not show internal name in cart tooltips 2022-11-15 09:55:53 +01:00
Richard SchreiberandGitHub 4f21bf8001 Calendar: add label „continued“ to event’s title 2022-11-15 08:19:41 +01:00
Raphael MichelandGitHub e32e7e2a50 Add clever handling of plus button in cart with voucher (#2893) 2022-11-14 16:55:39 +01:00
Raphael MichelandGitHub 5b8228bea0 PPv2: Improve error handling (#2899) 2022-11-14 16:55:30 +01:00
Raphael Michel a628f605a6 Send refund webhooks correctly when refunds are created via API 2022-11-14 12:23:49 +01:00
Martin GrossandGitHub e658744f67 PPv2: Do not PATCH custom_id and description for APMs (#2898) 2022-11-14 11:46:35 +01:00
Raphael Michel 776c5e9fa2 Set autocomplete="one-time-code" on TOTP field 2022-11-14 10:37:00 +01:00
Raphael Michel 46b5055aec Bump zeep to 4.2.* 2022-11-11 17:01:35 +01:00
Raphael Michel ef227deb2e Bump phonenumberslite to 8.13.* 2022-11-11 17:00:32 +01:00
Raphael Michel 30cfe1ef3c Bump pytest-xdist to 3.0.* 2022-11-11 16:59:46 +01:00
Raphael Michel 4d5c828e2a PDF editor: Update pdfjs from 1.7 to 3.0.279 2022-11-11 16:58:58 +01:00
Raphael Michel f509306b35 PDF editor: Fix browser detection 2022-11-11 16:58:58 +01:00
Richard SchreiberandGitHub 706e479cff Update vue to 2.7.14 (#2897) 2022-11-11 14:26:16 +01:00
Martin Gross a5be7dcff5 PayPal2: Allow all https-pages to be framed, addressing CSP+popover issues (Z#23111577) 2022-11-10 19:10:03 +01:00
Raphael Michel 845b3a866b Fix switching from SMTP to custom email 2022-11-10 17:38:05 +01:00
Raphael Michel 91e1e079e1 Allow private SMTP servers by default in debug version 2022-11-10 17:38:03 +01:00
Raphael Michel 9075c75a93 Fix test for exception type 2022-11-10 14:59:22 +01:00
Raphael Michel 7b97204f2f Port b9feceba (Do not show a price if there are mandatory non-free addons) to voucher redemption 2022-11-10 14:48:55 +01:00
Raphael Michel dfedf09656 PDF renderer: Normalize unicode before printing text 2022-11-10 13:53:15 +01:00
Raphael Michel 655cfe0afd Bump django-redis to 5.2.* 2022-11-10 09:17:26 +01:00
Raphael Michel faf17f824e Bump django-hijack to 3.2.* 2022-11-10 09:17:26 +01:00
Raphael Michel fbf52a5219 Bump Pillow to 9.3.* 2022-11-10 09:17:26 +01:00
Richard SchreiberandRaphael Michel 9466c57c35 Translations: Update Greek
Currently translated at 58.2% (2847 of 4888 strings)

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

powered by weblate
2022-11-10 09:17:11 +01:00
exbuandRaphael Michel 806ef8477b Translations: Update Dutch (informal) (nl_Informal)
Currently translated at 82.6% (4040 of 4888 strings)

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

powered by weblate
2022-11-10 09:17:11 +01:00
Raphael MichelandRaphael Michel 7cb654706a Translations: Update German (informal) (de_Informal)
Currently translated at 99.6% (4873 of 4888 strings)

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

powered by weblate
2022-11-10 09:17:11 +01:00
Raphael MichelandRaphael Michel dea448e0f8 Translations: Update German
Currently translated at 99.6% (4889 of 4904 strings)

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

powered by weblate
2022-11-10 09:17:11 +01:00
Dennis LichtenthälerandRaphael Michel 98b413249a Translations: Update German
Currently translated at 100.0% (4889 of 4889 strings)

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

powered by weblate
2022-11-10 09:17:11 +01:00
Raphael MichelandGitHub 4630c1fe8b Allow to charge a cancellation fee on unpaid orders (#2845) 2022-11-10 09:11:43 +01:00
Raphael MichelandGitHub bb718375e9 Stripe: Allow to set a custom statement descriptor suffix (#2883) 2022-11-10 09:11:35 +01:00
Martin Gross 7d2dd722bd PayPal: Fix loading of Smart Payment Buttons on APM payment page (regression introduced in #2875) 2022-11-09 15:04:35 +01:00
Raphael Michel 2adbd3cd4a Fix isort complain 2022-11-08 18:24:33 +01:00
Raphael Michel fb483ad00e Add comment to test 2022-11-08 18:07:50 +01:00
Raphael Michel 9cef65f359 API: Fix carts with addons/bundles not being created correctly 2022-11-08 18:03:16 +01:00
Raphael Michel ceeb69856b API: Support is_bundled during order creation 2022-11-08 16:55:35 +01:00
Raphael Michel c184187e59 Improve error handling for CSV parsing in voucher bulk creation 2022-11-08 10:27:31 +01:00
Raphael Michel 8ca38bdbaf Badges: Use ExportError instead of OrderError 2022-11-08 10:24:56 +01:00
Raphael Michel 3ae42b0c57 Update po files
[CI skip]

Signed-off-by: Raphael Michel <michel@rami.io>
2022-11-07 16:22:46 +01:00
Raphael MichelandRaphael Michel 6368954ecb Translations: Update Ukrainian
Currently translated at 74.1% (3615 of 4878 strings)

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

powered by weblate
2022-11-07 16:22:13 +01:00
Fazenda DengoandRaphael Michel 26ebdb7113 Translations: Update Portuguese
Currently translated at 3.8% (187 of 4878 strings)

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

powered by weblate
2022-11-07 16:22:13 +01:00
Fazenda DengoandRaphael Michel a1cb0b386b Translations: Update Portuguese (Portugal)
Currently translated at 63.1% (127 of 201 strings)

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

powered by weblate
2022-11-07 16:22:13 +01:00
Fazenda DengoandRaphael Michel d46e1aba52 Translations: Update Portuguese (Portugal)
Currently translated at 76.6% (3737 of 4878 strings)

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

powered by weblate
2022-11-07 16:22:13 +01:00
Dennis LichtenthälerandRaphael Michel 1f41184f9e Translations: Update German
Currently translated at 100.0% (4878 of 4878 strings)

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

powered by weblate
2022-11-07 16:22:13 +01:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2c746dffb2 Bump @babel/preset-env from 7.19.3 to 7.20.2 in /src/pretix/static/npm_dir (#2886)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-07 16:06:25 +01:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
84bd4e0e94 Bump @rollup/plugin-node-resolve from 14.1.0 to 15.0.1 in /src/pretix/static/npm_dir (#2877)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-07 16:06:12 +01:00
Raphael Michel 93f8b38745 SMTP settings: Don't replace password with ***** 2022-11-07 16:05:33 +01:00
Raphael Michel 4110d6ec15 Do some basic cleaning on dynamic subjects 2022-11-07 15:58:18 +01:00
9bea383ff0 Make all email subjects configurable (#2884)
Co-authored-by: Richard Schreiber <schreiber@rami.io>
2022-11-07 15:50:09 +01:00
Raphael Michel 2287c8b34c Bump django-filter to 22.1 2022-11-07 15:35:31 +01:00
Raphael Michel f7a129854e Bump pytest-mock to 3.10 2022-11-07 15:35:31 +01:00
Raphael Michel a96fccef63 Bump pyjwt to 2.6.* 2022-11-07 15:35:31 +01:00
Raphael Michel dc5a85b39e PDF: Fix another crash if unknown font is used
see also PRETIXEU-7K4
2022-11-07 15:35:31 +01:00
dependabot[bot]andRaphael Michel 23f9fb4a9a Bump @rollup/plugin-babel in /src/pretix/static/npm_dir
Bumps [@rollup/plugin-babel](https://github.com/rollup/plugins/tree/HEAD/packages/babel) from 5.3.1 to 6.0.2.
- [Release notes](https://github.com/rollup/plugins/releases)
- [Changelog](https://github.com/rollup/plugins/blob/master/packages/babel/CHANGELOG.md)
- [Commits](https://github.com/rollup/plugins/commits/babel-v6.0.2/packages/babel)

---
updated-dependencies:
- dependency-name: "@rollup/plugin-babel"
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-07 15:33:54 +01:00
dependabot[bot]andRaphael Michel 6130c45b3e Bump vue and vue-template-compiler in /src/pretix/static/npm_dir
Bumps [vue](https://github.com/vuejs/core) and [vue-template-compiler](https://github.com/vuejs/vue). These dependencies needed to be updated together.

Updates `vue` from 2.7.10 to 2.7.13
- [Release notes](https://github.com/vuejs/core/releases)
- [Changelog](https://github.com/vuejs/core/blob/main/CHANGELOG.md)
- [Commits](https://github.com/vuejs/core/commits)

Updates `vue-template-compiler` from 2.7.10 to 2.7.13
- [Release notes](https://github.com/vuejs/vue/releases)
- [Changelog](https://github.com/vuejs/vue/blob/main/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue/compare/v2.7.10...v2.7.13)

---
updated-dependencies:
- dependency-name: vue
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: vue-template-compiler
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-07 15:33:44 +01:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
83840c4024 Bump @babel/core from 7.19.3 to 7.19.6 in /src/pretix/static/npm_dir (#2880)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-07 15:33:33 +01:00
Maciej SzymczakandRaphael Michel 02d1d1e0c3 Translations: Update Polish
Currently translated at 14.1% (688 of 4878 strings)

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

powered by weblate
2022-11-07 09:08:18 +01:00
Maciej SzymczakandRaphael Michel f641f0fdd1 Translations: Update Polish
Currently translated at 13.8% (677 of 4878 strings)

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

powered by weblate
2022-11-07 09:08:18 +01:00
Raphael Michel 0c827c94a8 Fix mail text preview for languages down below in the list 2022-11-04 13:18:07 +01:00
Raphael Michel 4fb76f1b55 API: Fix overriding date_admission during event clone 2022-11-04 10:39:21 +01:00
Raphael Michel cb3b1f3ac5 API: Add discount to order position serializer 2022-11-03 15:29:20 +01:00
Richard SchreiberandGitHub 0b95f89882 Fix paypal disabling continue button (Z#23110784) (#2875) 2022-11-03 13:27:30 +01:00
Raphael Michel bccd7cd1a4 API: Fix setting plugins during event creation 2022-11-01 18:39:01 +01:00
Richard Schreiber 9c33078a40 Fix isort error 2022-11-01 17:15:27 +01:00
Raphael Michel 6403e5370a Don't crash if a exporter signal returns None 2022-11-01 13:40:22 +01:00
Raphael Michel 3fe2a0455f Fix crash in CartManager 2022-11-01 12:14:30 +01:00
6956b198ae Update translations (#2874)
Co-authored-by: Raphael Michel <michel@rami.io>
2022-11-01 11:27:26 +01:00
Raphael Michel 36f7a3d3a3 Update po files
[CI skip]

Signed-off-by: Raphael Michel <michel@rami.io>
2022-10-31 16:56:46 +01:00
Fazenda DengoandRaphael Michel 587e1a1c96 Translations: Update Portuguese (Portugal)
Currently translated at 76.6% (3737 of 4877 strings)

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

powered by weblate
2022-10-31 16:56:14 +01:00
Raphael Michel 8707ab5277 Use a more human-friendly file name for calendar attachments 2022-10-31 16:55:49 +01:00
Raphael Michel 4f6fa84fa7 Fix locking timeout no longer working after redis version change 2022-10-31 16:02:42 +01:00
Raphael Michel e76d13bf8e Improve logging of periodic command errors 2022-10-31 15:23:32 +01:00
Raphael Michel 39449ecbbe Sentry: Set propagate_traces=False 2022-10-31 14:13:59 +01:00
Raphael Michel 0204b42587 Revert "Attempt downgrade to sentry-sdk 1.8.*"
This reverts commit c1d1e437cc.
2022-10-31 14:10:11 +01:00
Raphael Michel c1d1e437cc Attempt downgrade to sentry-sdk 1.8.* 2022-10-31 12:30:03 +01:00
Raphael Michel 2fe0ceb4c7 PDF: Fail gracefully on unknown font 2022-10-31 09:53:06 +01:00
Raphael Michel 4cba292b57 Bump to 4.15.0.dev0 2022-10-28 13:34:05 +02:00
Raphael Michel 9e91197c5d Bump to 4.14.0 2022-10-28 13:32:30 +02:00
Raphael Michel 10a8cf3758 Split OverviewReport into modular functions 2022-10-27 22:41:05 +02:00
Raphael Michel d1deb35711 Add support for base_qs parameter in order_overview function 2022-10-27 22:41:05 +02:00
Raphael Michel c4d2b0bff7 Fix handling of default ticket layouts during event cloning 2022-10-27 21:55:08 +02:00
Raphael MichelandRaphael Michel 2d8ceb3255 Translations: Update German (informal) (de_Informal)
Currently translated at 100.0% (4877 of 4877 strings)

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

powered by weblate
2022-10-26 21:13:19 +02:00
Raphael MichelandRaphael Michel 176e5f115b Translations: Update German
Currently translated at 100.0% (4877 of 4877 strings)

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

powered by weblate
2022-10-26 21:13:19 +02:00
Raphael Michel 9939793e91 Update po files
[CI skip]

Signed-off-by: Raphael Michel <mail@raphaelmichel.de>
2022-10-26 20:57:05 +02:00
Raphael Michel 7d3cd16785 Add workaround for https://github.com/getsentry/sentry-python/issues/1700 2022-10-26 11:58:44 +02:00
Raphael MichelandGitHub 7c5fac306a Bank transfer: Match orders based on invoice number (#2867) 2022-10-26 11:06:45 +02:00
Raphael Michel 37683781d0 Fix incorrect variable use in test 2022-10-26 10:49:48 +02:00
Raphael MichelandGitHub 89dda69205 Allow to sort export of all tickets or badges by question answer (#2865) 2022-10-26 10:43:13 +02:00
Raphael Michel f2c72e5ff8 Bump pytest to 7.2.* 2022-10-26 09:39:40 +02:00
Raphael Michel 780ebfe120 Bump sentry-sdk to 1.10.* 2022-10-26 09:39:40 +02:00
Raphael Michel c7d5b687f3 Bump django-countries to 7.4.* 2022-10-26 09:39:40 +02:00
Raphael Michel 5fcb51f372 Bump sepaxml to 2.5.* 2022-10-26 09:39:40 +02:00
FlorianKohlerb88f86e20d524626andRaphael Michel 9b08f1b286 Translations: Update French
Currently translated at 47.0% (2291 of 4870 strings)

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

powered by weblate
2022-10-26 09:21:54 +02:00
Raphael Michel 4f35be7a25 Fix isort issue 2022-10-25 22:35:16 +02:00
Raphael Michel 884dbff4b8 Log details of API exceptions 2022-10-25 17:57:25 +02:00
Raphael Michel 51768eaef9 Add support for request ID headers 2022-10-25 17:17:59 +02:00
Raphael Michel 45f579caf2 Vouchers: Fix label on redemption page 2022-10-25 15:00:00 +02:00
fyksenandRaphael Michel a29dbd88ac Translations: Update Norwegian Bokmål
Currently translated at 7.0% (344 of 4870 strings)

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

powered by weblate
2022-10-25 14:55:12 +02:00
fyksenandRaphael Michel 957337b091 Translations: Update Norwegian Bokmål
Currently translated at 7.0% (343 of 4870 strings)

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

powered by weblate
2022-10-25 14:55:12 +02:00
Raphael Michel 4983073172 API: Fix crash with deletion of cart positions with add-ons 2022-10-25 12:08:58 +02:00
Raphael Michel b99d21df69 Fix crash in event creation with very long event names 2022-10-25 12:04:52 +02:00
Raphael Michel 2cfffe6526 Fix edge case in item add-on formset validation 2022-10-25 11:55:21 +02:00
Raphael Michel 87a413ea42 API: Enforce that Item.default_price can't be null 2022-10-25 11:39:48 +02:00
Raphael Michel 4146437380 Do not ask people to enter an address if they can't 2022-10-25 09:27:02 +02:00
Richard SchreiberandGitHub b4a7369642 Fix: make hidden form inputs visible, if invalid (Z#23110236) 2022-10-21 11:11:45 +02:00
Raphael Michel f9b51a8abb Fix incorrect handling of native customer logins 2022-10-20 18:07:46 +02:00
Raphael MichelandGitHub d69d70cfb1 Voucher: Add min_usages parameter (#2853) 2022-10-20 18:07:24 +02:00
Martin GrossandGitHub ba2d908a89 Security Profiles: Add stripeterminal.paymentintent to POS (#2850) 2022-10-19 17:57:44 +02:00
Raphael Michel c05abcbccd Bump stripe to 4.2.* and raise Stripe API version 2022-10-19 17:55:55 +02:00
Martin GrossandGitHub e16fd61bec Stripe Connect: Fix account name retrieval (#2857) 2022-10-19 17:55:34 +02:00
Raphael Michel a29d69d8f7 Fix subevent calender closed after month switch 2022-10-19 17:35:40 +02:00
Raphael Michel e063ad7dda Set payment_banktransfer_invoice_immediately by default 2022-10-19 17:28:22 +02:00
Raphael Michel 7c2bacf3b5 Fix crash on rendering error 404 page 2022-10-19 16:52:35 +02:00
Raphael Michel c921ca4e65 API: Fix crash when sorting orderpositions by attendee name 2022-10-19 15:32:29 +02:00
204 changed files with 174514 additions and 144568 deletions
+5 -2
View File
@@ -14,10 +14,13 @@ on:
- 'src/pretix/static/**' - 'src/pretix/static/**'
- 'src/tests/**' - 'src/tests/**'
permissions:
contents: read # to fetch code (actions/checkout)
jobs: jobs:
spelling: spelling:
name: Spellcheck name: Spellcheck
runs-on: ubuntu-latest runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Set up Python 3.8 - name: Set up Python 3.8
@@ -31,7 +34,7 @@ jobs:
restore-keys: | restore-keys: |
${{ runner.os }}-pip- ${{ runner.os }}-pip-
- name: Install system packages - name: Install system packages
run: sudo apt update && sudo apt install enchant hunspell aspell-en run: sudo apt update && sudo apt install enchant-2 hunspell aspell-en
- name: Install Dependencies - name: Install Dependencies
run: pip3 install -Ur requirements.txt run: pip3 install -Ur requirements.txt
working-directory: ./doc working-directory: ./doc
+6 -3
View File
@@ -12,9 +12,12 @@ on:
- 'doc/**' - 'doc/**'
- 'src/pretix/locale/**' - 'src/pretix/locale/**'
permissions:
contents: read # to fetch code (actions/checkout)
jobs: jobs:
compile: compile:
runs-on: ubuntu-latest runs-on: ubuntu-22.04
name: Check gettext syntax name: Check gettext syntax
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
@@ -40,7 +43,7 @@ jobs:
run: python manage.py compilejsi18n run: python manage.py compilejsi18n
working-directory: ./src working-directory: ./src
spelling: spelling:
runs-on: ubuntu-latest runs-on: ubuntu-22.04
name: Spellcheck name: Spellcheck
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
@@ -55,7 +58,7 @@ jobs:
restore-keys: | restore-keys: |
${{ runner.os }}-pip- ${{ runner.os }}-pip-
- name: Install system packages - name: Install system packages
run: sudo apt update && sudo apt install enchant hunspell hunspell-de-de aspell-en aspell-de run: sudo apt update && sudo apt install enchant-2 hunspell hunspell-de-de aspell-en aspell-de
- name: Install Dependencies - name: Install Dependencies
run: pip3 install -e ".[dev]" run: pip3 install -e ".[dev]"
working-directory: ./src working-directory: ./src
+6 -3
View File
@@ -12,10 +12,13 @@ on:
- 'src/pretix/locale/**' - 'src/pretix/locale/**'
- 'src/pretix/static/**' - 'src/pretix/static/**'
permissions:
contents: read # to fetch code (actions/checkout)
jobs: jobs:
isort: isort:
name: isort name: isort
runs-on: ubuntu-latest runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Set up Python 3.8 - name: Set up Python 3.8
@@ -36,7 +39,7 @@ jobs:
working-directory: ./src working-directory: ./src
flake: flake:
name: flake8 name: flake8
runs-on: ubuntu-latest runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Set up Python 3.8 - name: Set up Python 3.8
@@ -57,7 +60,7 @@ jobs:
working-directory: ./src working-directory: ./src
licenseheader: licenseheader:
name: licenseheaders name: licenseheaders
runs-on: ubuntu-latest runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Set up Python 3.8 - name: Set up Python 3.8
+9 -6
View File
@@ -12,23 +12,26 @@ on:
- 'doc/**' - 'doc/**'
- 'src/pretix/locale/**' - 'src/pretix/locale/**'
permissions:
contents: read # to fetch code (actions/checkout)
jobs: jobs:
test: test:
runs-on: ubuntu-latest runs-on: ubuntu-22.04
name: Tests name: Tests
strategy: strategy:
matrix: matrix:
python-version: ["3.7", "3.8", "3.9"] python-version: ["3.7", "3.9", "3.10"]
database: [sqlite, postgres, mysql] database: [sqlite, postgres, mysql]
exclude: exclude:
- database: mysql - database: mysql
python-version: "3.8" python-version: "3.10"
- database: mysql - database: mysql
python-version: "3.9" python-version: "3.9"
- database: sqlite - database: sqlite
python-version: "3.7" python-version: "3.7"
- database: sqlite - database: sqlite
python-version: "3.8" python-version: "3.10"
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- uses: getong/mariadb-action@v1.1 - uses: getong/mariadb-action@v1.1
@@ -55,7 +58,7 @@ jobs:
restore-keys: | restore-keys: |
${{ runner.os }}-pip- ${{ runner.os }}-pip-
- name: Install system dependencies - name: Install system dependencies
run: sudo apt update && sudo apt install gettext mariadb-client-10.3 run: sudo apt update && sudo apt install gettext mariadb-client
- name: Install Python dependencies - name: Install Python dependencies
run: pip3 install -e ".[dev]" mysqlclient psycopg2-binary run: pip3 install -e ".[dev]" mysqlclient psycopg2-binary
working-directory: ./src working-directory: ./src
@@ -76,4 +79,4 @@ jobs:
with: with:
file: src/coverage.xml file: src/coverage.xml
fail_ci_if_error: true fail_ci_if_error: true
if: matrix.database == 'postgres' && matrix.python-version == '3.8' if: matrix.database == 'postgres' && matrix.python-version == '3.10'
+3
View File
@@ -117,6 +117,9 @@ Example::
``loglevel`` ``loglevel``
Set console and file log level (``DEBUG``, ``INFO``, ``WARNING``, ``ERROR`` or ``CRITICAL``). Defaults to ``INFO``. Set console and file log level (``DEBUG``, ``INFO``, ``WARNING``, ``ERROR`` or ``CRITICAL``). Defaults to ``INFO``.
``request_id_header``
Specifies the name of a header that should be used for logging request IDs. Off by default.
Locale settings Locale settings
--------------- ---------------
+17
View File
@@ -178,6 +178,7 @@ tax_rule integer The ID of the u
secret string Secret code printed on the tickets for validation secret string Secret code printed on the tickets for validation
addon_to integer Internal ID of the position this position is an add-on for (or ``null``) addon_to integer Internal ID of the position this position is an add-on for (or ``null``)
subevent integer ID of the date inside an event series this position belongs to (or ``null``). subevent integer ID of the date inside an event series this position belongs to (or ``null``).
discount integer ID of a discount that has been used during the creation of this position in some way (or ``null``).
pseudonymization_id string A random ID, e.g. for use in lead scanning apps pseudonymization_id string A random ID, e.g. for use in lead scanning apps
checkins list of objects List of **successful** check-ins with this ticket checkins list of objects List of **successful** check-ins with this ticket
├ id integer Internal ID of the check-in event ├ id integer Internal ID of the check-in event
@@ -272,6 +273,15 @@ created datetime Date and time o
comment string Reason for refund (shown to the customer in some cases, can be ``null``). comment string Reason for refund (shown to the customer in some cases, can be ``null``).
execution_date datetime Date and time of completion of this refund (or ``null``) execution_date datetime Date and time of completion of this refund (or ``null``)
provider string Identification string of the payment provider provider string Identification string of the payment provider
details object Refund-specific information. This is a dictionary
with various fields that can be different between
payment providers, versions, payment states, etc. If
you read this field, you always need to be able to
deal with situations where values that you expect are
missing. Mostly, the field contains various IDs that
can be used for matching with other systems. If a
payment provider does not implement this feature,
the object is empty.
===================================== ========================== ======================================================= ===================================== ========================== =======================================================
List of all orders List of all orders
@@ -371,6 +381,7 @@ List of all orders
"secret": "z3fsn8jyufm5kpk768q69gkbyr5f4h6w", "secret": "z3fsn8jyufm5kpk768q69gkbyr5f4h6w",
"addon_to": null, "addon_to": null,
"subevent": null, "subevent": null,
"discount": null,
"pseudonymization_id": "MQLJvANO3B", "pseudonymization_id": "MQLJvANO3B",
"seat": null, "seat": null,
"checkins": [ "checkins": [
@@ -546,6 +557,7 @@ Fetching individual orders
"secret": "z3fsn8jyufm5kpk768q69gkbyr5f4h6w", "secret": "z3fsn8jyufm5kpk768q69gkbyr5f4h6w",
"addon_to": null, "addon_to": null,
"subevent": null, "subevent": null,
"discount": null,
"pseudonymization_id": "MQLJvANO3B", "pseudonymization_id": "MQLJvANO3B",
"seat": null, "seat": null,
"checkins": [ "checkins": [
@@ -1487,6 +1499,7 @@ List of all order positions
"tax_rule": null, "tax_rule": null,
"tax_value": "0.00", "tax_value": "0.00",
"secret": "z3fsn8jyufm5kpk768q69gkbyr5f4h6w", "secret": "z3fsn8jyufm5kpk768q69gkbyr5f4h6w",
"discount": null,
"pseudonymization_id": "MQLJvANO3B", "pseudonymization_id": "MQLJvANO3B",
"seat": null, "seat": null,
"addon_to": null, "addon_to": null,
@@ -1597,6 +1610,7 @@ Fetching individual positions
"secret": "z3fsn8jyufm5kpk768q69gkbyr5f4h6w", "secret": "z3fsn8jyufm5kpk768q69gkbyr5f4h6w",
"addon_to": null, "addon_to": null,
"subevent": null, "subevent": null,
"discount": null,
"pseudonymization_id": "MQLJvANO3B", "pseudonymization_id": "MQLJvANO3B",
"seat": null, "seat": null,
"checkins": [ "checkins": [
@@ -2319,6 +2333,7 @@ Order refund endpoints
"created": "2017-12-01T10:00:00Z", "created": "2017-12-01T10:00:00Z",
"execution_date": "2017-12-04T12:13:12Z", "execution_date": "2017-12-04T12:13:12Z",
"comment": "Cancellation", "comment": "Cancellation",
"details": {},
"provider": "banktransfer" "provider": "banktransfer"
} }
] ]
@@ -2362,6 +2377,7 @@ Order refund endpoints
"created": "2017-12-01T10:00:00Z", "created": "2017-12-01T10:00:00Z",
"execution_date": "2017-12-04T12:13:12Z", "execution_date": "2017-12-04T12:13:12Z",
"comment": "Cancellation", "comment": "Cancellation",
"details": {},
"provider": "banktransfer" "provider": "banktransfer"
} }
@@ -2419,6 +2435,7 @@ Order refund endpoints
"created": "2017-12-01T10:00:00Z", "created": "2017-12-01T10:00:00Z",
"execution_date": null, "execution_date": null,
"comment": "Cancellation", "comment": "Cancellation",
"details": {},
"provider": "manual" "provider": "manual"
} }
+2
View File
@@ -19,6 +19,8 @@ max_usages integer The maximum num
redeemed (default: 1). redeemed (default: 1).
redeemed integer The number of times this voucher already has been redeemed integer The number of times this voucher already has been
redeemed. redeemed.
min_usages integer The minimum number of times this voucher must be
redeemed on first usage (default: 1).
valid_until datetime The voucher expiration date (or ``null``). valid_until datetime The voucher expiration date (or ``null``).
block_quota boolean If ``true``, quota is blocked for this voucher. block_quota boolean If ``true``, quota is blocked for this voucher.
allow_ignore_quota boolean If ``true``, this voucher can be redeemed even if a allow_ignore_quota boolean If ``true``, this voucher can be redeemed even if a
+2
View File
@@ -126,6 +126,8 @@ The provider class
.. automethod:: api_payment_details .. automethod:: api_payment_details
.. automethod:: api_refund_details
.. automethod:: matching_id .. automethod:: matching_id
.. automethod:: shred_payment_info .. automethod:: shred_payment_info
+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 # 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/>. # <https://www.gnu.org/licenses/>.
# #
__version__ = "4.14.1.dev0" __version__ = "4.15.0.dev0"
+1
View File
@@ -196,6 +196,7 @@ class PretixPosSecurityProfile(AllowListSecurityProfile):
('POST', 'plugins:pretix_posbackend:posdebuglogentry-bulk-create'), ('POST', 'plugins:pretix_posbackend:posdebuglogentry-bulk-create'),
('GET', 'plugins:pretix_posbackend:poscashier-list'), ('GET', 'plugins:pretix_posbackend:poscashier-list'),
('POST', 'plugins:pretix_posbackend:stripeterminal.token'), ('POST', 'plugins:pretix_posbackend:stripeterminal.token'),
('POST', 'plugins:pretix_posbackend:stripeterminal.paymentintent'),
('PUT', 'plugins:pretix_posbackend:file.upload'), ('PUT', 'plugins:pretix_posbackend:file.upload'),
('GET', 'api-v1:revokedsecrets-list'), ('GET', 'api-v1:revokedsecrets-list'),
('GET', 'api-v1:event.settings'), ('GET', 'api-v1:event.settings'),
+9
View File
@@ -19,11 +19,17 @@
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see # 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/>. # <https://www.gnu.org/licenses/>.
# #
import logging
import ujson
from rest_framework import exceptions
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.views import exception_handler, status from rest_framework.views import exception_handler, status
from pretix.base.services.locking import LockTimeoutException from pretix.base.services.locking import LockTimeoutException
logger = logging.getLogger(__name__)
def custom_exception_handler(exc, context): def custom_exception_handler(exc, context):
response = exception_handler(exc, context) response = exception_handler(exc, context)
@@ -37,4 +43,7 @@ def custom_exception_handler(exc, context):
} }
) )
if isinstance(exc, exceptions.APIException):
logger.info(f'API Exception [{exc.status_code}]: {ujson.dumps(exc.detail)}')
return response return response
+2
View File
@@ -237,12 +237,14 @@ class CartPositionCreateSerializer(BaseCartPositionCreateSerializer):
for addon_data in addons_data: for addon_data in addons_data:
addon_data['addon_to'] = cp addon_data['addon_to'] = cp
addon_data['is_bundled'] = False addon_data['is_bundled'] = False
addon_data['cart_id'] = cp.cart_id
super().create(addon_data) super().create(addon_data)
if bundled_data: if bundled_data:
for bundle_data in bundled_data: for bundle_data in bundled_data:
bundle_data['addon_to'] = cp bundle_data['addon_to'] = cp
bundle_data['is_bundled'] = True bundle_data['is_bundled'] = True
bundle_data['cart_id'] = cp.cart_id
super().create(bundle_data) super().create(bundle_data)
return cp return cp
+9 -1
View File
@@ -411,7 +411,8 @@ class CloneEventSerializer(EventSerializer):
has_subevents = validated_data.pop('has_subevents', None) has_subevents = validated_data.pop('has_subevents', None)
tz = validated_data.pop('timezone', None) tz = validated_data.pop('timezone', None)
sales_channels = validated_data.pop('sales_channels', None) sales_channels = validated_data.pop('sales_channels', None)
new_event = super().create(validated_data) date_admission = validated_data.pop('date_admission', None)
new_event = super().create({**validated_data, 'plugins': None})
event = Event.objects.filter(slug=self.context['event'], organizer=self.context['organizer'].pk).first() event = Event.objects.filter(slug=self.context['event'], organizer=self.context['organizer'].pk).first()
new_event.copy_data_from(event) new_event.copy_data_from(event)
@@ -426,6 +427,10 @@ class CloneEventSerializer(EventSerializer):
new_event.sales_channels = sales_channels new_event.sales_channels = sales_channels
if has_subevents is not None: if has_subevents is not None:
new_event.has_subevents = has_subevents new_event.has_subevents = has_subevents
if has_subevents is not None:
new_event.has_subevents = has_subevents
if date_admission is not None:
new_event.date_admission = date_admission
new_event.save() new_event.save()
if tz: if tz:
new_event.settings.timezone = tz new_event.settings.timezone = tz
@@ -755,6 +760,9 @@ class EventSettingsSerializer(SettingsSerializer):
'invoice_logo_image', 'invoice_logo_image',
'cancel_allow_user', 'cancel_allow_user',
'cancel_allow_user_until', 'cancel_allow_user_until',
'cancel_allow_user_unpaid_keep',
'cancel_allow_user_unpaid_keep_fees',
'cancel_allow_user_unpaid_keep_percentage',
'cancel_allow_user_paid', 'cancel_allow_user_paid',
'cancel_allow_user_paid_until', 'cancel_allow_user_paid_until',
'cancel_allow_user_paid_keep', 'cancel_allow_user_paid_keep',
+2
View File
@@ -184,6 +184,8 @@ class ItemSerializer(I18nAwareModelSerializer):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.fields['default_price'].allow_null = False
self.fields['default_price'].required = True
if not self.read_only: if not self.read_only:
self.fields['require_membership_types'].queryset = self.context['event'].organizer.membership_types.all() self.fields['require_membership_types'].queryset = self.context['event'].organizer.membership_types.all()
self.fields['grant_membership_type'].queryset = self.context['event'].organizer.membership_types.all() self.fields['grant_membership_type'].queryset = self.context['event'].organizer.membership_types.all()
+14 -4
View File
@@ -410,13 +410,13 @@ class OrderPositionSerializer(I18nAwareModelSerializer):
class Meta: class Meta:
model = OrderPosition model = OrderPosition
fields = ('id', 'order', 'positionid', 'item', 'variation', 'price', 'attendee_name', 'attendee_name_parts', fields = ('id', 'order', 'positionid', 'item', 'variation', 'price', 'attendee_name', 'attendee_name_parts',
'company', 'street', 'zipcode', 'city', 'country', 'state', 'company', 'street', 'zipcode', 'city', 'country', 'state', 'discount',
'attendee_email', 'voucher', 'tax_rate', 'tax_value', 'secret', 'addon_to', 'subevent', 'checkins', 'attendee_email', 'voucher', 'tax_rate', 'tax_value', 'secret', 'addon_to', 'subevent', 'checkins',
'downloads', 'answers', 'tax_rule', 'pseudonymization_id', 'pdf_data', 'seat', 'canceled') 'downloads', 'answers', 'tax_rule', 'pseudonymization_id', 'pdf_data', 'seat', 'canceled')
read_only_fields = ( read_only_fields = (
'id', 'order', 'positionid', 'item', 'variation', 'price', 'voucher', 'tax_rate', 'tax_value', 'secret', 'id', 'order', 'positionid', 'item', 'variation', 'price', 'voucher', 'tax_rate', 'tax_value', 'secret',
'addon_to', 'subevent', 'checkins', 'downloads', 'answers', 'tax_rule', 'pseudonymization_id', 'pdf_data', 'addon_to', 'subevent', 'checkins', 'downloads', 'answers', 'tax_rule', 'pseudonymization_id', 'pdf_data',
'seat', 'canceled' 'seat', 'canceled', 'discount',
) )
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@@ -553,12 +553,22 @@ class OrderPaymentSerializer(I18nAwareModelSerializer):
'details') 'details')
class RefundDetailsField(serializers.Field):
def to_representation(self, value: OrderRefund):
pp = value.payment_provider
if not pp:
return {}
return pp.api_refund_details(value)
class OrderRefundSerializer(I18nAwareModelSerializer): class OrderRefundSerializer(I18nAwareModelSerializer):
payment = SlugRelatedField(slug_field='local_id', read_only=True) payment = SlugRelatedField(slug_field='local_id', read_only=True)
details = RefundDetailsField(source='*', allow_null=True, read_only=True)
class Meta: class Meta:
model = OrderRefund model = OrderRefund
fields = ('local_id', 'state', 'source', 'amount', 'payment', 'created', 'execution_date', 'comment', 'provider') fields = ('local_id', 'state', 'source', 'amount', 'payment', 'created', 'execution_date', 'comment', 'provider',
'details')
class OrderURLField(serializers.URLField): class OrderURLField(serializers.URLField):
@@ -721,7 +731,7 @@ class OrderPositionCreateSerializer(I18nAwareModelSerializer):
class Meta: class Meta:
model = OrderPosition model = OrderPosition
fields = ('positionid', 'item', 'variation', 'price', 'attendee_name', 'attendee_name_parts', 'attendee_email', fields = ('positionid', 'item', 'variation', 'price', 'attendee_name', 'attendee_name_parts', 'attendee_email',
'company', 'street', 'zipcode', 'city', 'country', 'state', 'company', 'street', 'zipcode', 'city', 'country', 'state', 'is_bundled',
'secret', 'addon_to', 'subevent', 'answers', 'seat', 'voucher') 'secret', 'addon_to', 'subevent', 'answers', 'seat', 'voucher')
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
+1 -1
View File
@@ -61,7 +61,7 @@ class VoucherSerializer(I18nAwareModelSerializer):
class Meta: class Meta:
model = Voucher model = Voucher
fields = ('id', 'code', 'max_usages', 'redeemed', 'valid_until', 'block_quota', fields = ('id', 'code', 'max_usages', 'redeemed', 'min_usages', 'valid_until', 'block_quota',
'allow_ignore_quota', 'price_mode', 'value', 'item', 'variation', 'quota', 'allow_ignore_quota', 'price_mode', 'value', 'item', 'variation', 'quota',
'tag', 'comment', 'subevent', 'show_hidden_items', 'seat') 'tag', 'comment', 'subevent', 'show_hidden_items', 'seat')
read_only_fields = ('id', 'redeemed') read_only_fields = ('id', 'redeemed')
+5
View File
@@ -92,6 +92,11 @@ class CartPositionViewSet(CreateModelMixin, DestroyModelMixin, viewsets.ReadOnly
def perform_create(self, serializer): def perform_create(self, serializer):
raise NotImplementedError() raise NotImplementedError()
@transaction.atomic()
def perform_destroy(self, instance):
instance.addons.all().delete()
instance.delete()
def _require_locking(self, quota_diff, voucher_use_diff, seat_diff): def _require_locking(self, quota_diff, voucher_use_diff, seat_diff):
if voucher_use_diff or seat_diff: if voucher_use_diff or seat_diff:
# If any vouchers or seats are used, we lock to make sure we don't redeem them to often # If any vouchers or seats are used, we lock to make sure we don't redeem them to often
+12 -2
View File
@@ -33,6 +33,7 @@
# License for the specific language governing permissions and limitations under the License. # License for the specific language governing permissions and limitations under the License.
import django_filters import django_filters
from django.conf import settings
from django.db import transaction from django.db import transaction
from django.db.models import Prefetch, ProtectedError, Q from django.db.models import Prefetch, ProtectedError, Q
from django.utils.timezone import now from django.utils.timezone import now
@@ -241,13 +242,17 @@ class EventViewSet(viewsets.ModelViewSet):
except Event.DoesNotExist: except Event.DoesNotExist:
raise ValidationError('Event to copy from was not found') raise ValidationError('Event to copy from was not found')
# Ensure that .installed() is only called when we NOT clone
plugins = serializer.validated_data.pop('plugins', None)
serializer.validated_data['plugins'] = None
new_event = serializer.save(organizer=self.request.organizer) new_event = serializer.save(organizer=self.request.organizer)
if copy_from: if copy_from:
new_event.copy_data_from(copy_from) new_event.copy_data_from(copy_from)
if 'plugins' in serializer.validated_data: if plugins is not None:
new_event.set_active_plugins(serializer.validated_data['plugins']) new_event.set_active_plugins(plugins)
if 'is_public' in serializer.validated_data: if 'is_public' in serializer.validated_data:
new_event.is_public = serializer.validated_data['is_public'] new_event.is_public = serializer.validated_data['is_public']
if 'testmode' in serializer.validated_data: if 'testmode' in serializer.validated_data:
@@ -256,12 +261,17 @@ class EventViewSet(viewsets.ModelViewSet):
new_event.sales_channels = serializer.validated_data['sales_channels'] new_event.sales_channels = serializer.validated_data['sales_channels']
if 'has_subevents' in serializer.validated_data: if 'has_subevents' in serializer.validated_data:
new_event.has_subevents = serializer.validated_data['has_subevents'] new_event.has_subevents = serializer.validated_data['has_subevents']
if 'date_admission' in serializer.validated_data:
new_event.date_admission = serializer.validated_data['date_admission']
new_event.save() new_event.save()
if 'timezone' in serializer.validated_data: if 'timezone' in serializer.validated_data:
new_event.settings.timezone = serializer.validated_data['timezone'] new_event.settings.timezone = serializer.validated_data['timezone']
else: else:
serializer.instance.set_defaults() serializer.instance.set_defaults()
new_event.set_active_plugins(plugins if plugins is not None else settings.PRETIX_PLUGINS_DEFAULT.split(','))
new_event.save(update_fields=['plugins'])
serializer.instance.log_action( serializer.instance.log_action(
'pretix.event.added', 'pretix.event.added',
user=self.request.user, user=self.request.user,
+21 -4
View File
@@ -61,6 +61,7 @@ from pretix.api.serializers.orderchange import (
OrderPositionCreateForExistingOrderSerializer, OrderPositionCreateForExistingOrderSerializer,
OrderPositionInfoPatchSerializer, OrderPositionInfoPatchSerializer,
) )
from pretix.api.views import RichOrderingFilter
from pretix.base.i18n import language from pretix.base.i18n import language
from pretix.base.models import ( from pretix.base.models import (
CachedCombinedTicket, CachedTicket, Checkin, Device, EventMetaValue, CachedCombinedTicket, CachedTicket, Checkin, Device, EventMetaValue,
@@ -679,28 +680,33 @@ class OrderViewSet(viewsets.ModelViewSet):
) )
if order.require_approval: if order.require_approval:
email_template = request.event.settings.mail_text_order_placed_require_approval email_template = request.event.settings.mail_text_order_placed_require_approval
subject_template = request.event.settings.mail_subject_order_placed_require_approval
log_entry = 'pretix.event.order.email.order_placed_require_approval' log_entry = 'pretix.event.order.email.order_placed_require_approval'
email_attendees = False email_attendees = False
elif free_flow: elif free_flow:
email_template = request.event.settings.mail_text_order_free email_template = request.event.settings.mail_text_order_free
subject_template = request.event.settings.mail_subject_order_free
log_entry = 'pretix.event.order.email.order_free' log_entry = 'pretix.event.order.email.order_free'
email_attendees = request.event.settings.mail_send_order_free_attendee email_attendees = request.event.settings.mail_send_order_free_attendee
email_attendees_template = request.event.settings.mail_text_order_free_attendee email_attendees_template = request.event.settings.mail_text_order_free_attendee
subject_attendees_template = request.event.settings.mail_subject_order_free_attendee
else: else:
email_template = request.event.settings.mail_text_order_placed email_template = request.event.settings.mail_text_order_placed
subject_template = request.event.settings.mail_subject_order_placed
log_entry = 'pretix.event.order.email.order_placed' log_entry = 'pretix.event.order.email.order_placed'
email_attendees = request.event.settings.mail_send_order_placed_attendee email_attendees = request.event.settings.mail_send_order_placed_attendee
email_attendees_template = request.event.settings.mail_text_order_placed_attendee email_attendees_template = request.event.settings.mail_text_order_placed_attendee
subject_attendees_template = request.event.settings.mail_subject_order_placed_attendee
_order_placed_email( _order_placed_email(
request.event, order, payment.payment_provider if payment else None, email_template, request.event, order, payment.payment_provider if payment else None, email_template, subject_template,
log_entry, invoice, payment, is_free=free_flow log_entry, invoice, payment, is_free=free_flow
) )
if email_attendees: if email_attendees:
for p in order.positions.all(): for p in order.positions.all():
if p.addon_to_id is None and p.attendee_email and p.attendee_email != order.email: if p.addon_to_id is None and p.attendee_email and p.attendee_email != order.email:
_order_placed_email_attendee(request.event, order, p, email_attendees_template, log_entry, _order_placed_email_attendee(request.event, order, p, email_attendees_template, subject_attendees_template,
is_free=free_flow) log_entry, is_free=free_flow)
if not free_flow and order.status == Order.STATUS_PAID and payment: if not free_flow and order.status == Order.STATUS_PAID and payment:
payment._send_paid_mail(invoice, None, '') payment._send_paid_mail(invoice, None, '')
@@ -930,7 +936,7 @@ with scopes_disabled():
class OrderPositionViewSet(viewsets.ModelViewSet): class OrderPositionViewSet(viewsets.ModelViewSet):
serializer_class = OrderPositionSerializer serializer_class = OrderPositionSerializer
queryset = OrderPosition.all.none() queryset = OrderPosition.all.none()
filter_backends = (DjangoFilterBackend, OrderingFilter) filter_backends = (DjangoFilterBackend, RichOrderingFilter)
ordering = ('order__datetime', 'positionid') ordering = ('order__datetime', 'positionid')
ordering_fields = ('order__code', 'order__datetime', 'positionid', 'attendee_name', 'order__status',) ordering_fields = ('order__code', 'order__datetime', 'positionid', 'attendee_name', 'order__status',)
filterset_class = OrderPositionFilter filterset_class = OrderPositionFilter
@@ -1604,6 +1610,17 @@ class RefundViewSet(CreateModelMixin, viewsets.ReadOnlyModelViewSet):
user=request.user if request.user.is_authenticated else None, user=request.user if request.user.is_authenticated else None,
auth=request.auth auth=request.auth
) )
if r.state in (OrderRefund.REFUND_STATE_DONE, OrderRefund.REFUND_STATE_CANCELED, OrderRefund.REFUND_STATE_FAILED):
r.order.log_action(
f'pretix.event.order.refund.{r.state}', {
'local_id': r.local_id,
'provider': r.provider,
},
user=request.user if request.user.is_authenticated else None,
auth=request.auth
)
if mark_refunded: if mark_refunded:
try: try:
mark_order_refunded( mark_order_refunded(
+29 -12
View File
@@ -23,6 +23,7 @@ import logging
from collections import defaultdict from collections import defaultdict
from decimal import Decimal from decimal import Decimal
from io import BytesIO from io import BytesIO
from itertools import groupby
from typing import Tuple from typing import Tuple
import bleach import bleach
@@ -554,31 +555,47 @@ class ClassicInvoiceRenderer(BaseReportlabInvoiceRenderer):
pgettext('invoice', 'Amount'), pgettext('invoice', 'Amount'),
)] )]
def _group_key(line):
return (line.description, line.tax_rate, line.tax_name, line.net_value, line.gross_value, line.subevent_id,
line.event_date_from, line.event_date_to)
total = Decimal('0.00') total = Decimal('0.00')
for line in self.invoice.lines.all(): for (description, tax_rate, tax_name, net_value, gross_value, *ignored), lines in groupby(self.invoice.lines.all(), key=_group_key):
lines = list(lines)
if has_taxes: if has_taxes:
if len(lines) > 1:
single_price_line = pgettext('invoice', 'Single price: {net_price} net / {gross_price} gross').format(
net_price=money_filter(net_value, self.invoice.event.currency),
gross_price=money_filter(gross_value, self.invoice.event.currency),
)
description = description + "\n" + single_price_line
tdata.append(( tdata.append((
Paragraph( Paragraph(
bleach.clean(line.description, tags=['br']).strip().replace('<br>', '<br/>').replace('\n', '<br />\n'), bleach.clean(description, tags=['br']).strip().replace('<br>', '<br/>').replace('\n', '<br />\n'),
self.stylesheet['Normal'] self.stylesheet['Normal']
), ),
"1", str(len(lines)),
localize(line.tax_rate) + " %", localize(tax_rate) + " %",
money_filter(line.net_value, self.invoice.event.currency), money_filter(net_value * len(lines), self.invoice.event.currency),
money_filter(line.gross_value, self.invoice.event.currency), money_filter(gross_value * len(lines), self.invoice.event.currency),
)) ))
else: else:
if len(lines) > 1:
single_price_line = pgettext('invoice', 'Single price: {price}').format(
price=money_filter(gross_value, self.invoice.event.currency),
)
description = description + "\n" + single_price_line
tdata.append(( tdata.append((
Paragraph( Paragraph(
bleach.clean(line.description, tags=['br']).strip().replace('<br>', '<br/>').replace('\n', '<br />\n'), bleach.clean(description, tags=['br']).strip().replace('<br>', '<br/>').replace('\n', '<br />\n'),
self.stylesheet['Normal'] self.stylesheet['Normal']
), ),
"1", str(len(lines)),
money_filter(line.gross_value, self.invoice.event.currency), money_filter(gross_value * len(lines), self.invoice.event.currency),
)) ))
taxvalue_map[line.tax_rate, line.tax_name] += line.tax_value taxvalue_map[tax_rate, tax_name] += (gross_value - net_value) * len(lines)
grossvalue_map[line.tax_rate, line.tax_name] += line.gross_value grossvalue_map[tax_rate, tax_name] += gross_value * len(lines)
total += line.gross_value total += gross_value * len(lines)
if has_taxes: if has_taxes:
tdata.append([ tdata.append([
@@ -103,6 +103,8 @@ class Command(BaseCommand):
with language(locale), override(timezone): with language(locale), override(timezone):
for receiver, response in signal_result: for receiver, response in signal_result:
if not response:
return None
ex = response(e, o, report_status) ex = response(e, o, report_status)
if ex.identifier == options['export_provider']: if ex.identifier == options['export_provider']:
params = json.loads(options.get('parameters') or '{}') params = json.loads(options.get('parameters') or '{}')
@@ -79,9 +79,9 @@ class Command(BaseCommand):
if settings.SENTRY_ENABLED: if settings.SENTRY_ENABLED:
from sentry_sdk import capture_exception from sentry_sdk import capture_exception
capture_exception(err) capture_exception(err)
self.stdout.write(self.style.ERROR(f'ERROR runperiodic {str(err)}\n')) self.stdout.write(self.style.ERROR(f'ERROR {name}: {str(err)}\n'))
else: else:
self.stdout.write(self.style.ERROR(f'ERROR runperiodic {str(err)}\n')) self.stdout.write(self.style.ERROR(f'ERROR {name}: {str(err)}\n'))
traceback.print_exc() traceback.print_exc()
else: else:
if options.get('verbosity') > 1: if options.get('verbosity') > 1:
@@ -0,0 +1,18 @@
# Generated by Django 3.2.12 on 2022-10-12 09:13
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('pretixbase', '0222_alter_question_unique_together'),
]
operations = [
migrations.AddField(
model_name='voucher',
name='min_usages',
field=models.PositiveIntegerField(default=1),
),
]
@@ -0,0 +1,18 @@
# Generated by Django 3.2.16 on 2022-11-14 11:32
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('pretixbase', '0223_voucher_min_usages'),
]
operations = [
migrations.AddField(
model_name='eventmetaproperty',
name='filter_allowed',
field=models.BooleanField(default=True),
),
]
+1 -1
View File
@@ -262,7 +262,7 @@ class Customer(LoggedModel):
) + '?id=' + self.identifier + '&token=' + token ) + '?id=' + self.identifier + '&token=' + token
mail( mail(
self.email, self.email,
_('Activate your account at {organizer}').format(organizer=self.organizer.name), self.organizer.settings.mail_subject_customer_registration,
self.organizer.settings.mail_text_customer_registration, self.organizer.settings.mail_text_customer_registration,
ctx, ctx,
locale=self.locale, locale=self.locale,
+6
View File
@@ -590,6 +590,7 @@ class Event(EventMixin, LoggedModel):
self.settings.event_list_type = 'calendar' self.settings.event_list_type = 'calendar'
self.settings.invoice_email_attachment = True self.settings.invoice_email_attachment = True
self.settings.name_scheme = 'given_family' self.settings.name_scheme = 'given_family'
self.settings.payment_banktransfer_invoice_immediately = True
@property @property
def social_image(self): def social_image(self):
@@ -1579,6 +1580,11 @@ class EventMetaProperty(LoggedModel):
verbose_name=_("Valid values"), verbose_name=_("Valid values"),
help_text=_("If you keep this empty, any value is allowed. Otherwise, enter one possible value per line.") help_text=_("If you keep this empty, any value is allowed. Otherwise, enter one possible value per line.")
) )
filter_allowed = models.BooleanField(
default=True, verbose_name=_("Can be used for filtering"),
help_text=_("This field will be shown to filter events or reports in the backend, and it can also be used "
"for hidden filter parameters in the frontend (e.g. using the widget).")
)
def full_clean(self, exclude=None, validate_unique=True): def full_clean(self, exclude=None, validate_unique=True):
super().full_clean(exclude, validate_unique) super().full_clean(exclude, validate_unique)
+22 -19
View File
@@ -581,18 +581,15 @@ class Item(LoggedModel):
def tax(self, price=None, base_price_is='auto', currency=None, invoice_address=None, override_tax_rate=None, include_bundled=False): def tax(self, price=None, base_price_is='auto', currency=None, invoice_address=None, override_tax_rate=None, include_bundled=False):
price = price if price is not None else self.default_price price = price if price is not None else self.default_price
if not self.tax_rule: bundled_sum = Decimal('0.00')
t = TaxedPrice(gross=price, net=price, tax=Decimal('0.00'), bundled_sum_net = Decimal('0.00')
rate=Decimal('0.00'), name='') bundled_sum_tax = Decimal('0.00')
else:
t = self.tax_rule.tax(price, base_price_is=base_price_is, invoice_address=invoice_address,
override_tax_rate=override_tax_rate, currency=currency or self.event.currency)
if include_bundled: if include_bundled:
for b in self.bundles.all(): for b in self.bundles.all():
if b.designated_price and b.bundled_item.tax_rule_id != self.tax_rule_id: if b.designated_price and b.bundled_item.tax_rule_id != self.tax_rule_id:
if b.bundled_variation: if b.bundled_variation:
bprice = b.bundled_variation.tax(b.designated_price * b.count, base_price_is='gross', bprice = b.bundled_variation.tax(b.designated_price * b.count,
base_price_is='gross',
invoice_address=invoice_address, invoice_address=invoice_address,
currency=currency) currency=currency)
else: else:
@@ -600,17 +597,23 @@ class Item(LoggedModel):
invoice_address=invoice_address, invoice_address=invoice_address,
base_price_is='gross', base_price_is='gross',
currency=currency) currency=currency)
if not self.tax_rule: bundled_sum += bprice.gross
compare_price = TaxedPrice(gross=b.designated_price * b.count, net=b.designated_price * b.count, bundled_sum_net += bprice.net
tax=Decimal('0.00'), rate=Decimal('0.00'), name='') bundled_sum_tax += bprice.tax
else:
compare_price = self.tax_rule.tax(b.designated_price * b.count, if not self.tax_rule:
override_tax_rate=override_tax_rate, t = TaxedPrice(gross=price - bundled_sum, net=price - bundled_sum, tax=Decimal('0.00'),
invoice_address=invoice_address, rate=Decimal('0.00'), name='')
currency=currency) else:
t.net += bprice.net - compare_price.net t = self.tax_rule.tax(price, base_price_is=base_price_is, invoice_address=invoice_address,
t.tax += bprice.tax - compare_price.tax override_tax_rate=override_tax_rate, currency=currency or self.event.currency,
t.name = "MIXED!" subtract_from_gross=bundled_sum)
if bundled_sum:
t.name = "MIXED!"
t.gross += bundled_sum
t.net += bundled_sum_net
t.tax += bundled_sum_tax
return t return t
+32 -16
View File
@@ -564,17 +564,30 @@ class Order(LockModel, LoggedModel):
@cached_property @cached_property
def user_cancel_fee(self): def user_cancel_fee(self):
fee = Decimal('0.00') fee = Decimal('0.00')
if self.event.settings.cancel_allow_user_paid_keep_fees: if self.status == Order.STATUS_PAID:
fee += self.fees.filter( if self.event.settings.cancel_allow_user_paid_keep_fees:
fee_type__in=(OrderFee.FEE_TYPE_PAYMENT, OrderFee.FEE_TYPE_SHIPPING, OrderFee.FEE_TYPE_SERVICE, fee += self.fees.filter(
OrderFee.FEE_TYPE_CANCELLATION) fee_type__in=(OrderFee.FEE_TYPE_PAYMENT, OrderFee.FEE_TYPE_SHIPPING, OrderFee.FEE_TYPE_SERVICE,
).aggregate( OrderFee.FEE_TYPE_CANCELLATION)
s=Sum('value') ).aggregate(
)['s'] or 0 s=Sum('value')
if self.event.settings.cancel_allow_user_paid_keep_percentage: )['s'] or 0
fee += self.event.settings.cancel_allow_user_paid_keep_percentage / Decimal('100.0') * (self.total - fee) if self.event.settings.cancel_allow_user_paid_keep_percentage:
if self.event.settings.cancel_allow_user_paid_keep: fee += self.event.settings.cancel_allow_user_paid_keep_percentage / Decimal('100.0') * (self.total - fee)
fee += self.event.settings.cancel_allow_user_paid_keep if self.event.settings.cancel_allow_user_paid_keep:
fee += self.event.settings.cancel_allow_user_paid_keep
else:
if self.event.settings.cancel_allow_user_unpaid_keep_fees:
fee += self.fees.filter(
fee_type__in=(OrderFee.FEE_TYPE_PAYMENT, OrderFee.FEE_TYPE_SHIPPING, OrderFee.FEE_TYPE_SERVICE,
OrderFee.FEE_TYPE_CANCELLATION)
).aggregate(
s=Sum('value')
)['s'] or 0
if self.event.settings.cancel_allow_user_unpaid_keep_percentage:
fee += self.event.settings.cancel_allow_user_unpaid_keep_percentage / Decimal('100.0') * (self.total - fee)
if self.event.settings.cancel_allow_user_unpaid_keep:
fee += self.event.settings.cancel_allow_user_unpaid_keep
return round_decimal(min(fee, self.total), self.event.currency) return round_decimal(min(fee, self.total), self.event.currency)
@property @property
@@ -642,10 +655,12 @@ class Order(LockModel, LoggedModel):
if self.user_cancel_deadline and now() > self.user_cancel_deadline: if self.user_cancel_deadline and now() > self.user_cancel_deadline:
return False return False
if self.status == Order.STATUS_PAID or self.payment_refund_sum > Decimal('0.00'): if self.status == Order.STATUS_PAID:
if self.total == Decimal('0.00'): if self.total == Decimal('0.00'):
return self.event.settings.cancel_allow_user return self.event.settings.cancel_allow_user
return self.event.settings.cancel_allow_user_paid return self.event.settings.cancel_allow_user_paid
elif self.payment_refund_sum > Decimal('0.00'):
return False
elif self.status == Order.STATUS_PENDING: elif self.status == Order.STATUS_PENDING:
return self.event.settings.cancel_allow_user return self.event.settings.cancel_allow_user
return False return False
@@ -1027,7 +1042,7 @@ class Order(LockModel, LoggedModel):
with language(self.locale, self.event.settings.region): with language(self.locale, self.event.settings.region):
email_template = self.event.settings.mail_text_resend_link email_template = self.event.settings.mail_text_resend_link
email_context = get_email_context(event=self.event, order=self) email_context = get_email_context(event=self.event, order=self)
email_subject = _('Your order: %(code)s') % {'code': self.code} email_subject = self.event.settings.mail_subject_resend_link
self.send_mail( self.send_mail(
email_subject, email_template, email_context, email_subject, email_template, email_context,
'pretix.event.order.email.resend', user=user, auth=auth, 'pretix.event.order.email.resend', user=user, auth=auth,
@@ -1738,8 +1753,8 @@ class OrderPayment(models.Model):
with language(self.order.locale, self.order.event.settings.region): with language(self.order.locale, self.order.event.settings.region):
email_template = self.order.event.settings.mail_text_order_paid_attendee email_template = self.order.event.settings.mail_text_order_paid_attendee
email_subject = self.order.event.settings.mail_subject_order_paid_attendee
email_context = get_email_context(event=self.order.event, order=self.order, position=position) email_context = get_email_context(event=self.order.event, order=self.order, position=position)
email_subject = _('Event registration confirmed: %(code)s') % {'code': self.order.code}
try: try:
position.send_mail( position.send_mail(
email_subject, email_template, email_context, email_subject, email_template, email_context,
@@ -1756,8 +1771,8 @@ class OrderPayment(models.Model):
with language(self.order.locale, self.order.event.settings.region): with language(self.order.locale, self.order.event.settings.region):
email_template = self.order.event.settings.mail_text_order_paid email_template = self.order.event.settings.mail_text_order_paid
email_subject = self.order.event.settings.mail_subject_order_paid
email_context = get_email_context(event=self.order.event, order=self.order, payment_info=mail_text) email_context = get_email_context(event=self.order.event, order=self.order, payment_info=mail_text)
email_subject = _('Payment received for your order: %(code)s') % {'code': self.order.code}
try: try:
self.order.send_mail( self.order.send_mail(
email_subject, email_template, email_context, email_subject, email_template, email_context,
@@ -2437,7 +2452,7 @@ class OrderPosition(AbstractPosition):
with language(self.order.locale, self.order.event.settings.region): with language(self.order.locale, self.order.event.settings.region):
email_template = self.event.settings.mail_text_resend_link email_template = self.event.settings.mail_text_resend_link
email_context = get_email_context(event=self.order.event, order=self.order, position=self) email_context = get_email_context(event=self.order.event, order=self.order, position=self)
email_subject = _('Your event registration: %(code)s') % {'code': self.order.code} email_subject = self.event.settings.mail_subject_resend_link
self.send_mail( self.send_mail(
email_subject, email_template, email_context, email_subject, email_template, email_context,
'pretix.event.order.email.resend', user=user, auth=auth, 'pretix.event.order.email.resend', user=user, auth=auth,
@@ -2722,6 +2737,7 @@ class CartPosition(AbstractPosition):
tax_rule=self.item.tax_rule, tax_rule=self.item.tax_rule,
invoice_address=invoice_address, invoice_address=invoice_address,
bundled_sum=sum([b.price_after_voucher for b in bundled_positions]), bundled_sum=sum([b.price_after_voucher for b in bundled_positions]),
is_bundled=self.is_bundled,
) )
if line_price.gross != self.line_price_gross or line_price.rate != self.tax_rate: if line_price.gross != self.line_price_gross or line_price.rate != self.tax_rate:
self.line_price_gross = line_price.gross self.line_price_gross = line_price.gross
+19 -1
View File
@@ -137,6 +137,8 @@ class Voucher(LoggedModel):
:type max_usages: int :type max_usages: int
:param redeemed: The number of times this voucher already has been redeemed :param redeemed: The number of times this voucher already has been redeemed
:type redeemed: int :type redeemed: int
:param min_usages: The minimum number of times this voucher must be redeemed
:type min_usages: int
:param valid_until: The expiration date of this voucher (optional) :param valid_until: The expiration date of this voucher (optional)
:type valid_until: datetime :type valid_until: datetime
:param block_quota: If set to true, this voucher will reserve quota for its holder :param block_quota: If set to true, this voucher will reserve quota for its holder
@@ -199,6 +201,14 @@ class Voucher(LoggedModel):
verbose_name=_("Redeemed"), verbose_name=_("Redeemed"),
default=0 default=0
) )
min_usages = models.PositiveIntegerField(
verbose_name=_("Minimum usages"),
help_text=_("If set to more than one, the voucher must be redeemed for this many products when it is used for "
"the first time. On later usages, it can also be used for lower numbers of products. Note that "
"this means that the total number of usages in some cases can be lower than this limit, e.g. in "
"case of cancellations."),
default=1
)
budget = models.DecimalField( budget = models.DecimalField(
verbose_name=_("Maximum discount budget"), verbose_name=_("Maximum discount budget"),
help_text=_("This is the maximum monetary amount that will be discounted using this voucher across all usages. " help_text=_("This is the maximum monetary amount that will be discounted using this voucher across all usages. "
@@ -350,6 +360,10 @@ class Voucher(LoggedModel):
'redeemed': redeemed '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.'),
)
@staticmethod @staticmethod
def clean_subevent(data, event): def clean_subevent(data, event):
@@ -464,7 +478,7 @@ class Voucher(LoggedModel):
if quota: if quota:
raise ValidationError(_('You need to choose a specific product if you select a seat.')) raise ValidationError(_('You need to choose a specific product if you select a seat.'))
if data.get('max_usages', 1) > 1: if data.get('max_usages', 1) > 1 or data.get('min_usages', 1) > 1:
raise ValidationError(_('Seat-specific vouchers can only be used once.')) raise ValidationError(_('Seat-specific vouchers can only be used once.'))
if item and seat.product != item: if item and seat.product != item:
@@ -567,6 +581,10 @@ class Voucher(LoggedModel):
else: else:
return bool(subevent.seating_plan) if subevent else self.event.seating_plan return bool(subevent.seating_plan) if subevent else self.event.seating_plan
@property
def min_usages_remaining(self):
return max(1, self.min_usages - self.redeemed)
@classmethod @classmethod
def annotate_budget_used_orders(cls, qs): def annotate_budget_used_orders(cls, qs):
opq = OrderPosition.objects.filter( opq = OrderPosition.objects.filter(
+1 -1
View File
@@ -216,7 +216,7 @@ class WaitingListEntry(LoggedModel):
with language(self.locale, self.event.settings.region): with language(self.locale, self.event.settings.region):
mail( mail(
self.email, self.email,
_('You have been selected from the waitinglist for {event}').format(event=str(self.event)), self.event.settings.mail_subject_waiting_list,
self.event.settings.mail_text_waiting_list, self.event.settings.mail_text_waiting_list,
get_email_context(event=self.event, waiting_list_entry=self), get_email_context(event=self.event, waiting_list_entry=self),
self.event, self.event,
+15
View File
@@ -877,6 +877,15 @@ class BasePaymentProvider:
""" """
return {} return {}
def api_refund_details(self, refund: OrderRefund):
"""
Will be called to populate the ``details`` parameter of the refund in the REST API.
:param refund: The refund in question.
:return: A serializable dictionary
"""
return {}
def matching_id(self, payment: OrderPayment): def matching_id(self, payment: OrderPayment):
""" """
Will be called to get an ID for matching this payment when comparing pretix records with records of an external Will be called to get an ID for matching this payment when comparing pretix records with records of an external
@@ -959,6 +968,9 @@ class BoxOfficeProvider(BasePaymentProvider):
"payment_data": payment.info_data.get('payment_data', {}), "payment_data": payment.info_data.get('payment_data', {}),
} }
def api_refund_details(self, refund: OrderRefund):
return self.api_payment_details(refund)
def payment_control_render(self, request, payment) -> str: def payment_control_render(self, request, payment) -> str:
if not payment.info: if not payment.info:
return return
@@ -1191,6 +1203,9 @@ class GiftCardPayment(BasePaymentProvider):
} }
} }
def api_refund_details(self, refund: OrderRefund):
return self.api_payment_details(refund)
def payment_partial_refund_supported(self, payment: OrderPayment) -> bool: def payment_partial_refund_supported(self, payment: OrderPayment) -> bool:
return True return True
+11 -1
View File
@@ -40,6 +40,7 @@ import os
import re import re
import subprocess import subprocess
import tempfile import tempfile
import unicodedata
import uuid import uuid
from collections import OrderedDict from collections import OrderedDict
from functools import partial from functools import partial
@@ -827,6 +828,13 @@ class Renderer:
if o['italic']: if o['italic']:
font += ' I' font += ' I'
try:
ad = getAscentDescent(font, float(o['fontsize']))
except KeyError: # font not known, fall back
logger.warning(f'Use of unknown font "{font}"')
font = 'Open Sans'
ad = getAscentDescent(font, float(o['fontsize']))
align_map = { align_map = {
'left': TA_LEFT, 'left': TA_LEFT,
'center': TA_CENTER, 'center': TA_CENTER,
@@ -853,10 +861,12 @@ class Renderer:
except: except:
logger.exception('Reshaping/Bidi fixes failed on string {}'.format(repr(text))) logger.exception('Reshaping/Bidi fixes failed on string {}'.format(repr(text)))
# reportlab does not support unicode combination characters
text = unicodedata.normalize("NFKC", text)
p = Paragraph(text, style=style) p = Paragraph(text, style=style)
w, h = p.wrapOn(canvas, float(o['width']) * mm, 1000 * mm) w, h = p.wrapOn(canvas, float(o['width']) * mm, 1000 * mm)
# p_size = p.wrap(float(o['width']) * mm, 1000 * mm) # p_size = p.wrap(float(o['width']) * mm, 1000 * mm)
ad = getAscentDescent(font, float(o['fontsize']))
canvas.saveState() canvas.saveState()
# The ascent/descent offsets here are not really proven to be correct, they're just empirical values to get # The ascent/descent offsets here are not really proven to be correct, they're just empirical values to get
# reportlab render similarly to browser canvas. # reportlab render similarly to browser canvas.
+83 -4
View File
@@ -110,6 +110,11 @@ error_messages = {
'positions have been removed from your cart.'), 'positions have been removed from your cart.'),
'price_too_high': _('The entered price is to high.'), 'price_too_high': _('The entered price is to high.'),
'voucher_invalid': _('This voucher code is not known in our database.'), 'voucher_invalid': _('This voucher code is not known in our database.'),
'voucher_min_usages': _('The voucher code "%(voucher)s" can only be used if you select at least %(number)s '
'matching products.'),
'voucher_min_usages_removed': _('The voucher code "%(voucher)s" can only be used if you select at least '
'%(number)s matching products. We have therefore removed some positions from '
'your cart that can no longer be purchased like this.'),
'voucher_redeemed': _('This voucher code has already been used the maximum number of times allowed.'), 'voucher_redeemed': _('This voucher code has already been used the maximum number of times allowed.'),
'voucher_redeemed_cart': _('This voucher code is currently locked since it is already contained in a cart. This ' 'voucher_redeemed_cart': _('This voucher code is currently locked since it is already contained in a cart. This '
'might mean that someone else is redeeming this voucher right now, or that you tried ' 'might mean that someone else is redeeming this voucher right now, or that you tried '
@@ -190,7 +195,7 @@ class CartManager:
AddOperation = namedtuple('AddOperation', ('count', 'item', 'variation', 'voucher', 'quotas', AddOperation = namedtuple('AddOperation', ('count', 'item', 'variation', 'voucher', 'quotas',
'addon_to', 'subevent', 'bundled', 'seat', 'listed_price', 'addon_to', 'subevent', 'bundled', 'seat', 'listed_price',
'price_after_voucher', 'custom_price_input', 'price_after_voucher', 'custom_price_input',
'custom_price_input_is_net')) 'custom_price_input_is_net', 'voucher_ignored'))
RemoveOperation = namedtuple('RemoveOperation', ('position',)) RemoveOperation = namedtuple('RemoveOperation', ('position',))
VoucherOperation = namedtuple('VoucherOperation', ('position', 'voucher', 'price_after_voucher')) VoucherOperation = namedtuple('VoucherOperation', ('position', 'voucher', 'price_after_voucher'))
ExtendOperation = namedtuple('ExtendOperation', ('position', 'count', 'item', 'variation', 'voucher', ExtendOperation = namedtuple('ExtendOperation', ('position', 'count', 'item', 'variation', 'voucher',
@@ -325,12 +330,16 @@ class CartManager:
(isinstance(op, self.ExtendOperation) and op.position.is_bundled) (isinstance(op, self.ExtendOperation) and op.position.is_bundled)
): ):
if op.item.require_voucher and op.voucher is None: if op.item.require_voucher and op.voucher is None:
if getattr(op, 'voucher_ignored', False):
raise CartError(error_messages['voucher_redeemed'])
raise CartError(error_messages['voucher_required']) raise CartError(error_messages['voucher_required'])
if ( if (
(op.item.hide_without_voucher or (op.variation and op.variation.hide_without_voucher)) and (op.item.hide_without_voucher or (op.variation and op.variation.hide_without_voucher)) and
(op.voucher is None or not op.voucher.show_hidden_items) (op.voucher is None or not op.voucher.show_hidden_items)
): ):
if getattr(op, 'voucher_ignored', False):
raise CartError(error_messages['voucher_redeemed'])
raise CartError(error_messages['voucher_required']) raise CartError(error_messages['voucher_required'])
if not op.item.is_available() or (op.variation and not op.variation.is_available()): if not op.item.is_available() or (op.variation and not op.variation.is_available()):
@@ -444,12 +453,15 @@ class CartManager:
if cp.is_bundled: if cp.is_bundled:
bundle = cp.addon_to.item.bundles.filter(bundled_item=cp.item, bundled_variation=cp.variation).first() bundle = cp.addon_to.item.bundles.filter(bundled_item=cp.item, bundled_variation=cp.variation).first()
if bundle: if bundle:
listed_price = bundle.designated_price or 0 listed_price = bundle.designated_price or Decimal('0.00')
else: else:
listed_price = cp.price listed_price = cp.price
price_after_voucher = listed_price price_after_voucher = listed_price
else: else:
listed_price = get_listed_price(cp.item, cp.variation, cp.subevent) if cp.addon_to_id and is_included_for_free(cp.item, cp.addon_to):
listed_price = Decimal('0.00')
else:
listed_price = get_listed_price(cp.item, cp.variation, cp.subevent)
if cp.voucher: if cp.voucher:
price_after_voucher = cp.voucher.calculate_price(listed_price) price_after_voucher = cp.voucher.calculate_price(listed_price)
else: else:
@@ -475,7 +487,7 @@ class CartManager:
self._check_item_constraints(op) self._check_item_constraints(op)
if cp.voucher: if cp.voucher:
self._voucher_use_diff[cp.voucher] += 1 self._voucher_use_diff[cp.voucher] += 2
self._operations.append(op) self._operations.append(op)
return err return err
@@ -524,6 +536,15 @@ class CartManager:
voucher_use_diff[voucher] += 1 voucher_use_diff[voucher] += 1
ops.append((listed_price - price_after_voucher, self.VoucherOperation(p, voucher, price_after_voucher))) ops.append((listed_price - price_after_voucher, self.VoucherOperation(p, voucher, price_after_voucher)))
for voucher, cnt in list(voucher_use_diff.items()):
if 0 < cnt < voucher.min_usages_remaining:
raise CartError(
_(error_messages['voucher_min_usages']) % {
'voucher': voucher.code,
'number': voucher.min_usages_remaining,
}
)
# If there are not enough voucher usages left for the full cart, let's apply them in the order that benefits # If there are not enough voucher usages left for the full cart, let's apply them in the order that benefits
# the user the most. # the user the most.
ops.sort(key=lambda k: k[0], reverse=True) ops.sort(key=lambda k: k[0], reverse=True)
@@ -572,6 +593,7 @@ class CartManager:
item = self._items_cache[i['item']] item = self._items_cache[i['item']]
variation = self._variations_cache[i['variation']] if i['variation'] is not None else None variation = self._variations_cache[i['variation']] if i['variation'] is not None else None
voucher = None voucher = None
voucher_ignored = False
if i.get('voucher'): if i.get('voucher'):
try: try:
@@ -581,6 +603,24 @@ class CartManager:
else: else:
voucher_use_diff[voucher] += i['count'] voucher_use_diff[voucher] += i['count']
if i.get('voucher_ignore_if_redeemed', False):
# This is a special case handling for when a user clicks "+" on an existing line in their cart
# that has a voucher attached. If the voucher still has redemptions left, we'll add another line
# with the same voucher, but if it does not we silently continue as if there was no voucher,
# leading to either a higher-priced ticket or an error. Still, this leads to less error cases
# than either of the possible default assumptions.
predicted_redeemed_after = (
voucher.redeemed +
CartPosition.objects.filter(voucher=voucher, expires__gte=self.now_dt).count() +
self._voucher_use_diff[voucher] +
voucher_use_diff[voucher]
)
if predicted_redeemed_after > voucher.max_usages:
i.pop('voucher')
voucher_ignored = True
voucher = None
voucher_use_diff[voucher] -= i['count']
# Fetch all quotas. If there are no quotas, this item is not allowed to be sold. # Fetch all quotas. If there are no quotas, this item is not allowed to be sold.
quotas = list(item.quotas.filter(subevent=subevent) quotas = list(item.quotas.filter(subevent=subevent)
if variation is None else variation.quotas.filter(subevent=subevent)) if variation is None else variation.quotas.filter(subevent=subevent))
@@ -627,6 +667,7 @@ class CartManager:
price_after_voucher=bundle.designated_price, price_after_voucher=bundle.designated_price,
custom_price_input=None, custom_price_input=None,
custom_price_input_is_net=False, custom_price_input_is_net=False,
voucher_ignored=False,
) )
self._check_item_constraints(bop, operations) self._check_item_constraints(bop, operations)
bundled.append(bop) bundled.append(bop)
@@ -656,6 +697,7 @@ class CartManager:
price_after_voucher=price_after_voucher, price_after_voucher=price_after_voucher,
custom_price_input=custom_price, custom_price_input=custom_price,
custom_price_input_is_net=self.event.settings.display_net_prices, custom_price_input_is_net=self.event.settings.display_net_prices,
voucher_ignored=voucher_ignored,
) )
self._check_item_constraints(op, operations) self._check_item_constraints(op, operations)
operations.append(op) operations.append(op)
@@ -787,6 +829,7 @@ class CartManager:
price_after_voucher=listed_price, price_after_voucher=listed_price,
custom_price_input=custom_price, custom_price_input=custom_price,
custom_price_input_is_net=self.event.settings.display_net_prices, custom_price_input_is_net=self.event.settings.display_net_prices,
voucher_ignored=False,
) )
self._check_item_constraints(op, operations) self._check_item_constraints(op, operations)
operations.append(op) operations.append(op)
@@ -915,6 +958,41 @@ class CartManager:
) )
return err return err
def _check_min_per_voucher(self):
vouchers = Counter()
for p in self.positions:
vouchers[p.voucher] += 1
for op in self._operations:
if isinstance(op, self.AddOperation):
vouchers[op.voucher] += op.count
elif isinstance(op, self.RemoveOperation):
vouchers[op.position.voucher] -= 1
err = None
for voucher, count in vouchers.items():
if not voucher or count == 0:
continue
if count < voucher.min_usages_remaining:
self._operations = [o for o in self._operations if not (
isinstance(o, self.AddOperation) and o.voucher and o.voucher.pk == voucher.pk
)]
removals = [o.position.pk for o in self._operations if isinstance(o, self.RemoveOperation)]
for p in self.positions:
if p.voucher_id == voucher.pk and p.pk not in removals:
self._operations.append(self.RemoveOperation(position=p))
err = _(error_messages['voucher_min_usages_removed']) % {
'voucher': voucher.code,
'number': voucher.min_usages_remaining,
}
if not err:
raise CartError(
_(error_messages['voucher_min_usages']) % {
'voucher': voucher.code,
'number': voucher.min_usages_remaining,
}
)
return err
def _perform_operations(self): def _perform_operations(self):
vouchers_ok = self._get_voucher_availability() vouchers_ok = self._get_voucher_availability()
quotas_ok = _get_quota_availability(self._quota_diff, self.now_dt) quotas_ok = _get_quota_availability(self._quota_diff, self.now_dt)
@@ -1171,6 +1249,7 @@ class CartManager:
err = self._delete_out_of_timeframe() err = self._delete_out_of_timeframe()
err = self.extend_expired_positions() or err err = self.extend_expired_positions() or err
err = err or self._check_min_per_voucher()
lockfn = NoLockManager lockfn = NoLockManager
if self._require_locking(): if self._require_locking():
+12 -10
View File
@@ -452,17 +452,19 @@ def build_preview_invoice_pdf(event):
if event.tax_rules.exists(): if event.tax_rules.exists():
for i, tr in enumerate(event.tax_rules.all()): for i, tr in enumerate(event.tax_rules.all()):
tax = tr.tax(Decimal('100.00'), base_price_is='gross') for j in range(150):
InvoiceLine.objects.create( tax = tr.tax(Decimal('100.00'), base_price_is='gross')
invoice=invoice, description=_("Sample product {}").format(i + 1), InvoiceLine.objects.create(
gross_value=tax.gross, tax_value=tax.tax, invoice=invoice, description=_("Sample product {}").format(i + 1),
tax_rate=tax.rate gross_value=tax.gross, tax_value=tax.tax,
) tax_rate=tax.rate
)
else: else:
InvoiceLine.objects.create( for i in range(150):
invoice=invoice, description=_("Sample product A"), InvoiceLine.objects.create(
gross_value=100, tax_value=0, tax_rate=0 invoice=invoice, description=_("Sample product A"),
) gross_value=100, tax_value=0, tax_rate=0
)
return event.invoice_renderer.generate(invoice) return event.invoice_renderer.generate(invoice)
+1 -1
View File
@@ -163,7 +163,7 @@ def lock_event_redis(event):
retries = 5 retries = 5
for i in range(retries): for i in range(retries):
try: try:
if lock.acquire(False): if lock.acquire(blocking=False):
return True return True
except RedisError: except RedisError:
logger.exception('Error locking an event') logger.exception('Error locking an event')
+4 -2
View File
@@ -63,6 +63,7 @@ from django.utils.timezone import now, override
from django.utils.translation import gettext as _, pgettext from django.utils.translation import gettext as _, pgettext
from django_scopes import scope, scopes_disabled from django_scopes import scope, scopes_disabled
from i18nfield.strings import LazyI18nString from i18nfield.strings import LazyI18nString
from text_unidecode import unidecode
from pretix.base.email import ClassicMailRenderer from pretix.base.email import ClassicMailRenderer
from pretix.base.i18n import language from pretix.base.i18n import language
@@ -196,7 +197,7 @@ def mail(email: Union[str, Sequence[str]], subject: str, template: Union[str, La
else: else:
sender = formataddr((settings.PRETIX_INSTANCE_NAME, sender)) sender = formataddr((settings.PRETIX_INSTANCE_NAME, sender))
subject = raw_subject = str(subject) subject = raw_subject = str(subject).replace('\n', ' ').replace('\r', '')[:900]
signature = "" signature = ""
bcc = [] bcc = []
@@ -431,8 +432,9 @@ def mail_send_task(self, *args, to: List[str], subject: str, body: str, html: st
} }
) )
if attach_ical: if attach_ical:
fname = re.sub('[^a-zA-Z0-9 ]', '-', unidecode(pgettext('attachment_filename', 'Calendar invite')))
for i, cal in enumerate(get_private_icals(event, [position] if position else order.positions.all())): for i, cal in enumerate(get_private_icals(event, [position] if position else order.positions.all())):
email.attach('event-{}.ics'.format(i), cal.serialize(), 'text/calendar') email.attach('{}{}.ics'.format(fname, f'-{i + 1}' if i > 0 else ''), cal.serialize(), 'text/calendar')
email = email_filter.send_chained(event, 'message', message=email, order=order, user=user) email = email_filter.send_chained(event, 'message', message=email, order=order, user=user)
+52 -24
View File
@@ -54,7 +54,7 @@ from django.db.transaction import get_connection
from django.dispatch import receiver from django.dispatch import receiver
from django.utils.functional import cached_property from django.utils.functional import cached_property
from django.utils.timezone import make_aware, now from django.utils.timezone import make_aware, now
from django.utils.translation import gettext as _, gettext_lazy from django.utils.translation import gettext as _
from django_scopes import scopes_disabled from django_scopes import scopes_disabled
from pretix.api.models import OAuthApplication from pretix.api.models import OAuthApplication
@@ -115,6 +115,8 @@ error_messages = {
'server was too busy. Please try again.'), 'server was too busy. Please try again.'),
'not_started': _('The booking period for this event has not yet started.'), 'not_started': _('The booking period for this event has not yet started.'),
'ended': _('The booking period has ended.'), 'ended': _('The booking period has ended.'),
'voucher_min_usages': _('The voucher code "%(voucher)s" can only be used if you select at least %(number)s '
'matching products.'),
'voucher_invalid': _('The voucher code used for one of the items in your cart is not known in our database.'), 'voucher_invalid': _('The voucher code used for one of the items in your cart is not known in our database.'),
'voucher_redeemed': _('The voucher code used for one of the items in your cart has already been used the maximum ' 'voucher_redeemed': _('The voucher code used for one of the items in your cart has already been used the maximum '
'number of times allowed. We removed this item from your cart.'), 'number of times allowed. We removed this item from your cart.'),
@@ -322,10 +324,10 @@ def approve_order(order, user=None, send_mail: bool=True, auth=None, force=False
with language(order.locale, order.event.settings.region): with language(order.locale, order.event.settings.region):
if order.total == Decimal('0.00'): if order.total == Decimal('0.00'):
email_template = order.event.settings.mail_text_order_approved_free email_template = order.event.settings.mail_text_order_approved_free
email_subject = _('Order approved and confirmed: %(code)s') % {'code': order.code} email_subject = order.event.settings.mail_subject_order_approved_free
else: else:
email_template = order.event.settings.mail_text_order_approved email_template = order.event.settings.mail_text_order_approved
email_subject = _('Order approved and awaiting payment: %(code)s') % {'code': order.code} email_subject = order.event.settings.mail_subject_order_approved
email_context = get_email_context(event=order.event, order=order) email_context = get_email_context(event=order.event, order=order)
try: try:
@@ -371,9 +373,9 @@ def deny_order(order, comment='', user=None, send_mail: bool=True, auth=None):
if send_mail: if send_mail:
email_template = order.event.settings.mail_text_order_denied email_template = order.event.settings.mail_text_order_denied
email_subject = order.event.settings.mail_subject_order_denied
email_context = get_email_context(event=order.event, order=order, comment=comment) email_context = get_email_context(event=order.event, order=order, comment=comment)
with language(order.locale, order.event.settings.region): with language(order.locale, order.event.settings.region):
email_subject = _('Order denied: %(code)s') % {'code': order.code}
try: try:
order.send_mail( order.send_mail(
email_subject, email_template, email_context, email_subject, email_template, email_context,
@@ -460,9 +462,13 @@ def _cancel_order(order, user=None, send_mail: bool=True, api_token=None, device
f._calculate_tax() f._calculate_tax()
f.save() f.save()
if order.payment_refund_sum < cancellation_fee: if cancellation_fee > order.total:
raise OrderError(_('The cancellation fee cannot be higher than the payment credit of this order.')) raise OrderError(_('The cancellation fee cannot be higher than the total amount of this order.'))
order.status = Order.STATUS_PAID elif order.payment_refund_sum < cancellation_fee:
order.status = Order.STATUS_PENDING
order.set_expires()
else:
order.status = Order.STATUS_PAID
order.total = cancellation_fee order.total = cancellation_fee
order.cancellation_date = now() order.cancellation_date = now()
order.save(update_fields=['status', 'cancellation_date', 'total']) order.save(update_fields=['status', 'cancellation_date', 'total'])
@@ -489,10 +495,10 @@ def _cancel_order(order, user=None, send_mail: bool=True, api_token=None, device
order.create_transactions() order.create_transactions()
if send_mail: if send_mail:
email_template = order.event.settings.mail_text_order_canceled
with language(order.locale, order.event.settings.region): with language(order.locale, order.event.settings.region):
email_template = order.event.settings.mail_text_order_canceled
email_subject = order.event.settings.mail_subject_order_canceled
email_context = get_email_context(event=order.event, order=order, comment=comment or "") email_context = get_email_context(event=order.event, order=order, comment=comment or "")
email_subject = _('Order canceled: %(code)s') % {'code': order.code}
try: try:
order.send_mail( order.send_mail(
email_subject, email_template, email_context, email_subject, email_template, email_context,
@@ -569,6 +575,7 @@ def _check_positions(event: Event, now_dt: datetime, positions: List[CartPositio
products_seen = Counter() products_seen = Counter()
q_avail = Counter() q_avail = Counter()
v_avail = Counter() v_avail = Counter()
v_usages = Counter()
v_budget = {} v_budget = {}
deleted_positions = set() deleted_positions = set()
seats_seen = set() seats_seen = set()
@@ -606,6 +613,7 @@ def _check_positions(event: Event, now_dt: datetime, positions: List[CartPositio
break break
if cp.voucher: if cp.voucher:
v_usages[cp.voucher] += 1
if cp.voucher not in v_avail: if cp.voucher not in v_avail:
redeemed_in_carts = CartPosition.objects.filter( redeemed_in_carts = CartPosition.objects.filter(
Q(voucher=cp.voucher) & Q(event=event) & Q(expires__gte=now_dt) Q(voucher=cp.voucher) & Q(event=event) & Q(expires__gte=now_dt)
@@ -717,6 +725,13 @@ def _check_positions(event: Event, now_dt: datetime, positions: List[CartPositio
# Sorry, can't let you keep that! # Sorry, can't let you keep that!
delete(cp) delete(cp)
for voucher, cnt in v_usages.items():
if 0 < cnt < voucher.min_usages_remaining:
raise OrderError(error_messages['voucher_min_usages'], {
'voucher': voucher.code,
'number': voucher.min_usages_remaining,
})
# Check prices # Check prices
sorted_positions = [cp for cp in sorted_positions if cp.pk and cp.pk not in deleted_positions] sorted_positions = [cp for cp in sorted_positions if cp.pk and cp.pk not in deleted_positions]
old_total = sum(cp.price for cp in sorted_positions) old_total = sum(cp.price for cp in sorted_positions)
@@ -927,13 +942,12 @@ def _create_order(event: Event, email: str, positions: List[CartPosition], now_d
return order, p return order, p
def _order_placed_email(event: Event, order: Order, pprov: BasePaymentProvider, email_template, log_entry: str, def _order_placed_email(event: Event, order: Order, pprov: BasePaymentProvider, email_template, subject_template,
invoice, payment: OrderPayment, is_free=False): log_entry: str, invoice, payment: OrderPayment, is_free=False):
email_context = get_email_context(event=event, order=order, payment=payment if pprov else None) email_context = get_email_context(event=event, order=order, payment=payment if pprov else None)
email_subject = gettext_lazy('Your order: {code}')
try: try:
order.send_mail( order.send_mail(
email_subject, email_template, email_context, subject_template, email_template, email_context,
log_entry, log_entry,
invoices=[invoice] if invoice and event.settings.invoice_email_attachment else [], invoices=[invoice] if invoice and event.settings.invoice_email_attachment else [],
attach_tickets=True, attach_tickets=True,
@@ -946,13 +960,13 @@ def _order_placed_email(event: Event, order: Order, pprov: BasePaymentProvider,
logger.exception('Order received email could not be sent') logger.exception('Order received email could not be sent')
def _order_placed_email_attendee(event: Event, order: Order, position: OrderPosition, email_template, log_entry: str, is_free=False): def _order_placed_email_attendee(event: Event, order: Order, position: OrderPosition, email_template, subject_template,
log_entry: str, is_free=False):
email_context = get_email_context(event=event, order=order, position=position) email_context = get_email_context(event=event, order=order, position=position)
email_subject = gettext_lazy('Your event registration: {code}')
try: try:
position.send_mail( position.send_mail(
email_subject, email_template, email_context, subject_template, email_template, email_context,
log_entry, log_entry,
invoices=[], invoices=[],
attach_tickets=True, attach_tickets=True,
@@ -1048,29 +1062,34 @@ def _perform_order(event: Event, payment_provider: str, position_ids: List[str],
if order.email: if order.email:
if order.require_approval: if order.require_approval:
email_template = event.settings.mail_text_order_placed_require_approval email_template = event.settings.mail_text_order_placed_require_approval
subject_template = event.settings.mail_subject_order_placed_require_approval
log_entry = 'pretix.event.order.email.order_placed_require_approval' log_entry = 'pretix.event.order.email.order_placed_require_approval'
email_attendees = False email_attendees = False
elif free_order_flow: elif free_order_flow:
email_template = event.settings.mail_text_order_free email_template = event.settings.mail_text_order_free
subject_template = event.settings.mail_subject_order_free
log_entry = 'pretix.event.order.email.order_free' log_entry = 'pretix.event.order.email.order_free'
email_attendees = event.settings.mail_send_order_free_attendee email_attendees = event.settings.mail_send_order_free_attendee
email_attendees_template = event.settings.mail_text_order_free_attendee email_attendees_template = event.settings.mail_text_order_free_attendee
subject_attendees_template = event.settings.mail_subject_order_free_attendee
else: else:
email_template = event.settings.mail_text_order_placed email_template = event.settings.mail_text_order_placed
subject_template = event.settings.mail_subject_order_placed
log_entry = 'pretix.event.order.email.order_placed' log_entry = 'pretix.event.order.email.order_placed'
email_attendees = event.settings.mail_send_order_placed_attendee email_attendees = event.settings.mail_send_order_placed_attendee
email_attendees_template = event.settings.mail_text_order_placed_attendee email_attendees_template = event.settings.mail_text_order_placed_attendee
subject_attendees_template = event.settings.mail_subject_order_placed_attendee
if sales_channel in event.settings.mail_sales_channel_placed_paid: if sales_channel in event.settings.mail_sales_channel_placed_paid:
_order_placed_email(event, order, pprov, email_template, log_entry, invoice, payment, _order_placed_email(event, order, pprov, email_template, subject_template, log_entry, invoice, payment,
is_free=free_order_flow) is_free=free_order_flow)
if email_attendees: if email_attendees:
for p in order.positions.all(): for p in order.positions.all():
if p.addon_to_id is None and p.attendee_email and p.attendee_email != order.email: if p.addon_to_id is None and p.attendee_email and p.attendee_email != order.email:
_order_placed_email_attendee(event, order, p, email_attendees_template, log_entry, _order_placed_email_attendee(event, order, p, email_attendees_template, subject_attendees_template, log_entry,
is_free=free_order_flow) is_free=free_order_flow)
return order.id return order.id
@@ -1082,8 +1101,16 @@ def expire_orders(sender, **kwargs):
event_id = None event_id = None
expire = None expire = None
for o in Order.objects.filter(expires__lt=now(), status=Order.STATUS_PENDING, qs = Order.objects.filter(
require_approval=False).select_related('event').order_by('event_id'): expires__lt=now(),
status=Order.STATUS_PENDING,
require_approval=False
).exclude(
Exists(
OrderFee.objects.filter(order_id=OuterRef('pk'), fee_type=OrderFee.FEE_TYPE_CANCELLATION)
)
).select_related('event').order_by('event_id')
for o in qs:
if o.event_id != event_id: if o.event_id != event_id:
expire = o.event.settings.get('payment_term_expire_automatically', as_type=bool) expire = o.event.settings.get('payment_term_expire_automatically', as_type=bool)
event_id = o.event_id event_id = o.event_id
@@ -1124,9 +1151,9 @@ def send_expiry_warnings(sender, **kwargs):
email_template = settings.mail_text_order_expire_warning email_template = settings.mail_text_order_expire_warning
email_context = get_email_context(event=o.event, order=o) email_context = get_email_context(event=o.event, order=o)
if settings.payment_term_expire_automatically: if settings.payment_term_expire_automatically:
email_subject = _('Your order is about to expire: %(code)s') % {'code': o.code} email_subject = settings.mail_subject_order_expire_warning
else: else:
email_subject = _('Your order is pending payment: %(code)s') % {'code': o.code} email_subject = settings.mail_subject_order_pending_warning
try: try:
o.send_mail( o.send_mail(
@@ -1199,8 +1226,8 @@ def send_download_reminders(sender, **kwargs):
o.download_reminder_sent = True o.download_reminder_sent = True
o.save(update_fields=['download_reminder_sent']) o.save(update_fields=['download_reminder_sent'])
email_template = event.settings.mail_text_download_reminder email_template = event.settings.mail_text_download_reminder
email_subject = event.settings.mail_subject_download_reminder
email_context = get_email_context(event=event, order=o) email_context = get_email_context(event=event, order=o)
email_subject = _('Your ticket is ready for download: %(code)s') % {'code': o.code}
try: try:
o.send_mail( o.send_mail(
email_subject, email_template, email_context, email_subject, email_template, email_context,
@@ -1223,6 +1250,7 @@ def send_download_reminders(sender, **kwargs):
continue continue
if p.addon_to_id is None and p.attendee_email and p.attendee_email != o.email: if p.addon_to_id is None and p.attendee_email and p.attendee_email != o.email:
email_template = event.settings.mail_text_download_reminder_attendee email_template = event.settings.mail_text_download_reminder_attendee
email_subject = event.settings.mail_subject_download_reminder_attendee
email_context = get_email_context(event=event, order=o, position=p) email_context = get_email_context(event=event, order=o, position=p)
try: try:
o.send_mail( o.send_mail(
@@ -1238,7 +1266,7 @@ def notify_user_changed_order(order, user=None, auth=None, invoices=[]):
with language(order.locale, order.event.settings.region): with language(order.locale, order.event.settings.region):
email_template = order.event.settings.mail_text_order_changed email_template = order.event.settings.mail_text_order_changed
email_context = get_email_context(event=order.event, order=order) email_context = get_email_context(event=order.event, order=order)
email_subject = _('Your order has been changed: %(code)s') % {'code': order.code} email_subject = order.event.settings.mail_subject_order_changed
try: try:
order.send_mail( order.send_mail(
email_subject, email_template, email_context, email_subject, email_template, email_context,
+3 -2
View File
@@ -117,7 +117,7 @@ def get_listed_price(item: Item, variation: ItemVariation = None, subevent: SubE
def get_line_price(price_after_voucher: Decimal, custom_price_input: Decimal, custom_price_input_is_net: bool, def get_line_price(price_after_voucher: Decimal, custom_price_input: Decimal, custom_price_input_is_net: bool,
tax_rule: TaxRule, invoice_address: InvoiceAddress, bundled_sum: Decimal) -> TaxedPrice: tax_rule: TaxRule, invoice_address: InvoiceAddress, bundled_sum: Decimal, is_bundled=False) -> TaxedPrice:
if not tax_rule: if not tax_rule:
tax_rule = TaxRule( tax_rule = TaxRule(
name='', name='',
@@ -135,7 +135,8 @@ def get_line_price(price_after_voucher: Decimal, custom_price_input: Decimal, cu
price = tax_rule.tax(max(custom_price_input, price.gross), base_price_is='gross', override_tax_rate=price.rate, price = tax_rule.tax(max(custom_price_input, price.gross), base_price_is='gross', override_tax_rate=price.rate,
invoice_address=invoice_address, subtract_from_gross=bundled_sum) invoice_address=invoice_address, subtract_from_gross=bundled_sum)
else: else:
price = tax_rule.tax(price_after_voucher, invoice_address=invoice_address, subtract_from_gross=bundled_sum) price = tax_rule.tax(price_after_voucher, invoice_address=invoice_address, subtract_from_gross=bundled_sum,
base_price_is='gross' if is_bundled else 'auto')
return price return price
+2 -2
View File
@@ -112,7 +112,7 @@ def dictsum(*dicts) -> dict:
def order_overview( def order_overview(
event: Event, subevent: SubEvent=None, date_filter='', date_from=None, date_until=None, fees=False, event: Event, subevent: SubEvent=None, date_filter='', date_from=None, date_until=None, fees=False,
admission_only=False admission_only=False, base_qs=None
) -> Tuple[List[Tuple[ItemCategory, List[Item]]], Dict[str, Tuple[Decimal, Decimal]]]: ) -> Tuple[List[Tuple[ItemCategory, List[Item]]], Dict[str, Tuple[Decimal, Decimal]]]:
items = event.items.all().select_related( items = event.items.all().select_related(
'category', # for re-grouping 'category', # for re-grouping
@@ -120,7 +120,7 @@ def order_overview(
'variations' 'variations'
).order_by('category__position', 'category_id', 'position', 'name') ).order_by('category__position', 'category_id', 'position', 'name')
qs = OrderPosition.all qs = OrderPosition.all if base_qs is None else base_qs
if isinstance(subevent, (list, QuerySet)): if isinstance(subevent, (list, QuerySet)):
qs = qs.filter(subevent__in=subevent) qs = qs.filter(subevent__in=subevent)
elif subevent: elif subevent:
+134 -3
View File
@@ -1421,6 +1421,45 @@ DEFAULTS = {
label=_("Customers can cancel their unpaid orders"), label=_("Customers can cancel their unpaid orders"),
) )
}, },
'cancel_allow_user_unpaid_keep': {
'default': '0.00',
'type': Decimal,
'form_class': forms.DecimalField,
'serializer_class': serializers.DecimalField,
'serializer_kwargs': dict(
max_digits=10, decimal_places=2
),
'form_kwargs': dict(
label=_("Charge a fixed cancellation fee"),
help_text=_("Only affects orders pending payments, a cancellation fee for free orders is never charged. "
"Note that it will be your responsibility to claim the cancellation fee from the user."),
)
},
'cancel_allow_user_unpaid_keep_fees': {
'default': 'False',
'type': bool,
'form_class': forms.BooleanField,
'serializer_class': serializers.BooleanField,
'form_kwargs': dict(
label=_("Charge payment, shipping and service fees"),
help_text=_("Only affects orders pending payments, a cancellation fee for free orders is never charged. "
"Note that it will be your responsibility to claim the cancellation fee from the user."),
)
},
'cancel_allow_user_unpaid_keep_percentage': {
'default': '0.00',
'type': Decimal,
'form_class': forms.DecimalField,
'serializer_class': serializers.DecimalField,
'serializer_kwargs': dict(
max_digits=10, decimal_places=2
),
'form_kwargs': dict(
label=_("Charge a percentual cancellation fee"),
help_text=_("Only affects orders pending payments, a cancellation fee for free orders is never charged. "
"Note that it will be your responsibility to claim the cancellation fee from the user."),
)
},
'cancel_allow_user_until': { 'cancel_allow_user_until': {
'default': None, 'default': None,
'type': RelativeDateWrapper, 'type': RelativeDateWrapper,
@@ -1708,6 +1747,14 @@ DEFAULTS = {
'type': LazyI18nString, 'type': LazyI18nString,
'default': "" 'default': ""
}, },
'mail_subject_resend_link': {
'type': LazyI18nString,
'default': LazyI18nString.from_gettext(gettext_noop("Your order: {code}")),
},
'mail_subject_resend_link_attendee': {
'type': LazyI18nString,
'default': LazyI18nString.from_gettext(gettext_noop("Your event registration: {code}")),
},
'mail_text_resend_link': { 'mail_text_resend_link': {
'type': LazyI18nString, 'type': LazyI18nString,
'default': LazyI18nString.from_gettext(gettext_noop("""Hello, 'default': LazyI18nString.from_gettext(gettext_noop("""Hello,
@@ -1721,6 +1768,10 @@ You can change your order details and view the status of your order at
Best regards, Best regards,
Your {event} team""")) Your {event} team"""))
}, },
'mail_subject_resend_all_links': {
'type': LazyI18nString,
'default': LazyI18nString.from_gettext(gettext_noop("Your orders for {event}")),
},
'mail_text_resend_all_links': { 'mail_text_resend_all_links': {
'type': LazyI18nString, 'type': LazyI18nString,
'default': LazyI18nString.from_gettext(gettext_noop("""Hello, 'default': LazyI18nString.from_gettext(gettext_noop("""Hello,
@@ -1733,6 +1784,10 @@ The list is as follows:
Best regards, Best regards,
Your {event} team""")) Your {event} team"""))
}, },
'mail_subject_order_free_attendee': {
'type': LazyI18nString,
'default': LazyI18nString.from_gettext(gettext_noop("Your event registration: {code}")),
},
'mail_text_order_free_attendee': { 'mail_text_order_free_attendee': {
'type': LazyI18nString, 'type': LazyI18nString,
'default': LazyI18nString.from_gettext(gettext_noop("""Hello {attendee_name}, 'default': LazyI18nString.from_gettext(gettext_noop("""Hello {attendee_name},
@@ -1745,6 +1800,14 @@ You can view the details and status of your ticket here:
Best regards, Best regards,
Your {event} team""")) Your {event} team"""))
}, },
'mail_send_order_free_attendee': {
'type': bool,
'default': 'False'
},
'mail_subject_order_free': {
'type': LazyI18nString,
'default': LazyI18nString.from_gettext(gettext_noop("Your order: {code}")),
},
'mail_text_order_free': { 'mail_text_order_free': {
'type': LazyI18nString, 'type': LazyI18nString,
'default': LazyI18nString.from_gettext(gettext_noop("""Hello, 'default': LazyI18nString.from_gettext(gettext_noop("""Hello,
@@ -1758,9 +1821,9 @@ You can change your order details and view the status of your order at
Best regards, Best regards,
Your {event} team""")) Your {event} team"""))
}, },
'mail_send_order_free_attendee': { 'mail_subject_order_placed_require_approval': {
'type': bool, 'type': LazyI18nString,
'default': 'False' 'default': LazyI18nString.from_gettext(gettext_noop("Your order: {code}")),
}, },
'mail_text_order_placed_require_approval': { 'mail_text_order_placed_require_approval': {
'type': LazyI18nString, 'type': LazyI18nString,
@@ -1776,6 +1839,10 @@ You can change your order details and view the status of your order at
Best regards, Best regards,
Your {event} team""")) Your {event} team"""))
}, },
'mail_subject_order_placed': {
'type': LazyI18nString,
'default': LazyI18nString.from_gettext(gettext_noop("Your order: {code}")),
},
'mail_text_order_placed': { 'mail_text_order_placed': {
'type': LazyI18nString, 'type': LazyI18nString,
'default': LazyI18nString.from_gettext(gettext_noop("""Hello, 'default': LazyI18nString.from_gettext(gettext_noop("""Hello,
@@ -1819,6 +1886,10 @@ Your {event} team"""))
'type': bool, 'type': bool,
'default': 'False' 'default': 'False'
}, },
'mail_subject_order_placed_attendee': {
'type': LazyI18nString,
'default': LazyI18nString.from_gettext(gettext_noop("Your event registration: {code}")),
},
'mail_text_order_placed_attendee': { 'mail_text_order_placed_attendee': {
'type': LazyI18nString, 'type': LazyI18nString,
'default': LazyI18nString.from_gettext(gettext_noop("""Hello {attendee_name}, 'default': LazyI18nString.from_gettext(gettext_noop("""Hello {attendee_name},
@@ -1831,6 +1902,10 @@ You can view the details and status of your ticket here:
Best regards, Best regards,
Your {event} team""")) Your {event} team"""))
}, },
'mail_subject_order_changed': {
'type': LazyI18nString,
'default': LazyI18nString.from_gettext(gettext_noop("Your order has been changed: {code}")),
},
'mail_text_order_changed': { 'mail_text_order_changed': {
'type': LazyI18nString, 'type': LazyI18nString,
'default': LazyI18nString.from_gettext(gettext_noop("""Hello, 'default': LazyI18nString.from_gettext(gettext_noop("""Hello,
@@ -1843,6 +1918,10 @@ You can view the status of your order at
Best regards, Best regards,
Your {event} team""")) Your {event} team"""))
}, },
'mail_subject_order_paid': {
'type': LazyI18nString,
'default': LazyI18nString.from_gettext(gettext_noop("Payment received for your order: {code}")),
},
'mail_text_order_paid': { 'mail_text_order_paid': {
'type': LazyI18nString, 'type': LazyI18nString,
'default': LazyI18nString.from_gettext(gettext_noop("""Hello, 'default': LazyI18nString.from_gettext(gettext_noop("""Hello,
@@ -1861,6 +1940,10 @@ Your {event} team"""))
'type': bool, 'type': bool,
'default': 'False' 'default': 'False'
}, },
'mail_subject_order_paid_attendee': {
'type': LazyI18nString,
'default': LazyI18nString.from_gettext(gettext_noop("Event registration confirmed: {code}")),
},
'mail_text_order_paid_attendee': { 'mail_text_order_paid_attendee': {
'type': LazyI18nString, 'type': LazyI18nString,
'default': LazyI18nString.from_gettext(gettext_noop("""Hello {attendee_name}, 'default': LazyI18nString.from_gettext(gettext_noop("""Hello {attendee_name},
@@ -1888,6 +1971,14 @@ Your {event} team"""))
'type': int, 'type': int,
'default': '3' 'default': '3'
}, },
'mail_subject_order_expire_warning': {
'type': LazyI18nString,
'default': LazyI18nString.from_gettext(gettext_noop("Your order is about to expire: {code}")),
},
'mail_subject_order_pending_warning': {
'type': LazyI18nString,
'default': LazyI18nString.from_gettext(gettext_noop("Your order is pending payment: {code}")),
},
'mail_text_order_expire_warning': { 'mail_text_order_expire_warning': {
'type': LazyI18nString, 'type': LazyI18nString,
'default': LazyI18nString.from_gettext(gettext_noop("""Hello, 'default': LazyI18nString.from_gettext(gettext_noop("""Hello,
@@ -1902,6 +1993,10 @@ You can view the payment information and the status of your order at
Best regards, Best regards,
Your {event} team""")) Your {event} team"""))
}, },
'mail_subject_waiting_list': {
'type': LazyI18nString,
'default': LazyI18nString.from_gettext(gettext_noop("You have been selected from the waitinglist for {event}")),
},
'mail_text_waiting_list': { 'mail_text_waiting_list': {
'type': LazyI18nString, 'type': LazyI18nString,
'default': LazyI18nString.from_gettext(gettext_noop("""Hello, 'default': LazyI18nString.from_gettext(gettext_noop("""Hello,
@@ -1931,6 +2026,10 @@ as possible to the next person on the waiting list:
Best regards, Best regards,
Your {event} team""")) Your {event} team"""))
}, },
'mail_subject_order_canceled': {
'type': LazyI18nString,
'default': LazyI18nString.from_gettext(gettext_noop("Order canceled: {code}")),
},
'mail_text_order_canceled': { 'mail_text_order_canceled': {
'type': LazyI18nString, 'type': LazyI18nString,
'default': LazyI18nString.from_gettext(gettext_noop("""Hello, 'default': LazyI18nString.from_gettext(gettext_noop("""Hello,
@@ -1945,6 +2044,10 @@ You can view the details of your order at
Best regards, Best regards,
Your {event} team""")) Your {event} team"""))
}, },
'mail_subject_order_approved': {
'type': LazyI18nString,
'default': LazyI18nString.from_gettext(gettext_noop("Order approved and awaiting payment: {code}")),
},
'mail_text_order_approved': { 'mail_text_order_approved': {
'type': LazyI18nString, 'type': LazyI18nString,
'default': LazyI18nString.from_gettext(gettext_noop("""Hello, 'default': LazyI18nString.from_gettext(gettext_noop("""Hello,
@@ -1961,6 +2064,10 @@ You can select a payment method and perform the payment here:
Best regards, Best regards,
Your {event} team""")) Your {event} team"""))
}, },
'mail_subject_order_approved_free': {
'type': LazyI18nString,
'default': LazyI18nString.from_gettext(gettext_noop("Order approved and confirmed: {code}")),
},
'mail_text_order_approved_free': { 'mail_text_order_approved_free': {
'type': LazyI18nString, 'type': LazyI18nString,
'default': LazyI18nString.from_gettext(gettext_noop("""Hello, 'default': LazyI18nString.from_gettext(gettext_noop("""Hello,
@@ -1974,6 +2081,10 @@ You can change your order details and view the status of your order at
Best regards, Best regards,
Your {event} team""")) Your {event} team"""))
}, },
'mail_subject_order_denied': {
'type': LazyI18nString,
'default': LazyI18nString.from_gettext(gettext_noop("Order denied: {code}")),
},
'mail_text_order_denied': { 'mail_text_order_denied': {
'type': LazyI18nString, 'type': LazyI18nString,
'default': LazyI18nString.from_gettext(gettext_noop("""Hello, 'default': LazyI18nString.from_gettext(gettext_noop("""Hello,
@@ -2007,6 +2118,10 @@ Your {event} team"""))
'type': bool, 'type': bool,
'default': 'False' 'default': 'False'
}, },
'mail_subject_download_reminder_attendee': {
'type': LazyI18nString,
'default': LazyI18nString.from_gettext(gettext_noop("Your ticket is ready for download: {code}")),
},
'mail_text_download_reminder_attendee': { 'mail_text_download_reminder_attendee': {
'type': LazyI18nString, 'type': LazyI18nString,
'default': LazyI18nString.from_gettext(gettext_noop("""Hello {attendee_name}, 'default': LazyI18nString.from_gettext(gettext_noop("""Hello {attendee_name},
@@ -2019,6 +2134,10 @@ Your {event} team"""))
Best regards, Best regards,
Your {event} team""")) Your {event} team"""))
}, },
'mail_subject_download_reminder': {
'type': LazyI18nString,
'default': LazyI18nString.from_gettext(gettext_noop("Your ticket is ready for download: {code}")),
},
'mail_text_download_reminder': { 'mail_text_download_reminder': {
'type': LazyI18nString, 'type': LazyI18nString,
'default': LazyI18nString.from_gettext(gettext_noop("""Hello, 'default': LazyI18nString.from_gettext(gettext_noop("""Hello,
@@ -2031,6 +2150,10 @@ If you did not do so already, you can download your ticket here:
Best regards, Best regards,
Your {event} team""")) Your {event} team"""))
}, },
'mail_subject_customer_registration': {
'type': LazyI18nString,
'default': LazyI18nString.from_gettext(gettext_noop("Activate your account at {organizer}")),
},
'mail_text_customer_registration': { 'mail_text_customer_registration': {
'type': LazyI18nString, 'type': LazyI18nString,
'default': LazyI18nString.from_gettext(gettext_noop("""Hello {name}, 'default': LazyI18nString.from_gettext(gettext_noop("""Hello {name},
@@ -2049,6 +2172,10 @@ Best regards,
Your {organizer} team""")) Your {organizer} team"""))
}, },
'mail_subject_customer_email_change': {
'type': LazyI18nString,
'default': LazyI18nString.from_gettext(gettext_noop("Confirm email address for your account at {organizer}")),
},
'mail_text_customer_email_change': { 'mail_text_customer_email_change': {
'type': LazyI18nString, 'type': LazyI18nString,
'default': LazyI18nString.from_gettext(gettext_noop("""Hello {name}, 'default': LazyI18nString.from_gettext(gettext_noop("""Hello {name},
@@ -2067,6 +2194,10 @@ Best regards,
Your {organizer} team""")) Your {organizer} team"""))
}, },
'mail_subject_customer_reset': {
'type': LazyI18nString,
'default': LazyI18nString.from_gettext(gettext_noop("Set a new password for your account at {organizer}")),
},
'mail_text_customer_reset': { 'mail_text_customer_reset': {
'type': LazyI18nString, 'type': LazyI18nString,
'default': LazyI18nString.from_gettext(gettext_noop("""Hello {name}, 'default': LazyI18nString.from_gettext(gettext_noop("""Hello {name},
+4
View File
@@ -64,6 +64,10 @@ class EventPluginSignal(django.dispatch.Signal):
# Send to all events! # Send to all events!
return True return True
# If sentry packed this in a wrapper, unpack that
if "sentry" in receiver.__module__:
receiver = receiver.__wrapped__
# Find the Django application this belongs to # Find the Django application this belongs to
searchpath = receiver.__module__ searchpath = receiver.__module__
core_module = any([searchpath.startswith(cm) for cm in settings.CORE_MODULES]) core_module = any([searchpath.startswith(cm) for cm in settings.CORE_MODULES])
+127 -4
View File
@@ -666,6 +666,9 @@ class CancelSettingsForm(SettingsForm):
'cancel_allow_user_until', 'cancel_allow_user_until',
'cancel_allow_user_paid', 'cancel_allow_user_paid',
'cancel_allow_user_paid_until', 'cancel_allow_user_paid_until',
'cancel_allow_user_unpaid_keep',
'cancel_allow_user_unpaid_keep_fees',
'cancel_allow_user_unpaid_keep_percentage',
'cancel_allow_user_paid_keep', 'cancel_allow_user_paid_keep',
'cancel_allow_user_paid_keep_fees', 'cancel_allow_user_paid_keep_fees',
'cancel_allow_user_paid_keep_percentage', 'cancel_allow_user_paid_keep_percentage',
@@ -927,6 +930,11 @@ class MailSettingsForm(SettingsForm):
required=True, required=True,
choices=[] choices=[]
) )
mail_subject_order_placed = I18nFormField(
label=_("Subject sent to order contact address"),
required=False,
widget=I18nTextInput,
)
mail_text_order_placed = I18nFormField( mail_text_order_placed = I18nFormField(
label=_("Text sent to order contact address"), label=_("Text sent to order contact address"),
required=False, required=False,
@@ -938,12 +946,22 @@ class MailSettingsForm(SettingsForm):
'tickets, the following email will be sent out to the attendees.'), 'tickets, the following email will be sent out to the attendees.'),
required=False, required=False,
) )
mail_subject_order_placed_attendee = I18nFormField(
label=_("Subject sent to attendees"),
required=False,
widget=I18nTextInput,
)
mail_text_order_placed_attendee = I18nFormField( mail_text_order_placed_attendee = I18nFormField(
label=_("Text sent to attendees"), label=_("Text sent to attendees"),
required=False, required=False,
widget=I18nTextarea, widget=I18nTextarea,
) )
mail_subject_order_paid = I18nFormField(
label=_("Subject sent to order contact address"),
required=False,
widget=I18nTextInput,
)
mail_text_order_paid = I18nFormField( mail_text_order_paid = I18nFormField(
label=_("Text sent to order contact address"), label=_("Text sent to order contact address"),
required=False, required=False,
@@ -955,12 +973,22 @@ class MailSettingsForm(SettingsForm):
'tickets, the following email will be sent out to the attendees.'), 'tickets, the following email will be sent out to the attendees.'),
required=False, required=False,
) )
mail_subject_order_paid_attendee = I18nFormField(
label=_("Subject sent to attendees"),
required=False,
widget=I18nTextInput,
)
mail_text_order_paid_attendee = I18nFormField( mail_text_order_paid_attendee = I18nFormField(
label=_("Text sent to attendees"), label=_("Text sent to attendees"),
required=False, required=False,
widget=I18nTextarea, widget=I18nTextarea,
) )
mail_subject_order_free = I18nFormField(
label=_("Subject sent to order contact address"),
required=False,
widget=I18nTextInput,
)
mail_text_order_free = I18nFormField( mail_text_order_free = I18nFormField(
label=_("Text sent to order contact address"), label=_("Text sent to order contact address"),
required=False, required=False,
@@ -972,22 +1000,47 @@ class MailSettingsForm(SettingsForm):
'tickets, the following email will be sent out to the attendees.'), 'tickets, the following email will be sent out to the attendees.'),
required=False, required=False,
) )
mail_subject_order_free_attendee = I18nFormField(
label=_("Subject sent to attendees"),
required=False,
widget=I18nTextInput,
)
mail_text_order_free_attendee = I18nFormField( mail_text_order_free_attendee = I18nFormField(
label=_("Text sent to attendees"), label=_("Text sent to attendees"),
required=False, required=False,
widget=I18nTextarea, widget=I18nTextarea,
) )
mail_subject_order_changed = I18nFormField(
label=_("Subject"),
required=False,
widget=I18nTextInput,
)
mail_text_order_changed = I18nFormField( mail_text_order_changed = I18nFormField(
label=_("Text"), label=_("Text"),
required=False, required=False,
widget=I18nTextarea, widget=I18nTextarea,
) )
mail_subject_resend_link = I18nFormField(
label=_("Subject (sent by admin)"),
required=False,
widget=I18nTextInput,
)
mail_subject_resend_link_attendee = I18nFormField(
label=_("Subject (sent by admin to attendee)"),
required=False,
widget=I18nTextInput,
)
mail_text_resend_link = I18nFormField( mail_text_resend_link = I18nFormField(
label=_("Text (sent by admin)"), label=_("Text (sent by admin)"),
required=False, required=False,
widget=I18nTextarea, widget=I18nTextarea,
) )
mail_subject_resend_all_links = I18nFormField(
label=_("Subject (requested by user)"),
required=False,
widget=I18nTextInput,
)
mail_text_resend_all_links = I18nFormField( mail_text_resend_all_links = I18nFormField(
label=_("Text (requested by user)"), label=_("Text (requested by user)"),
required=False, required=False,
@@ -1005,11 +1058,31 @@ class MailSettingsForm(SettingsForm):
required=False, required=False,
widget=I18nTextarea, widget=I18nTextarea,
) )
mail_subject_order_expire_warning = I18nFormField(
label=_("Subject (if order will expire automatically)"),
required=False,
widget=I18nTextInput,
)
mail_subject_order_pending_warning = I18nFormField(
label=_("Subject (if order will not expire automatically)"),
required=False,
widget=I18nTextInput,
)
mail_subject_waiting_list = I18nFormField(
label=_("Subject"),
required=False,
widget=I18nTextInput,
)
mail_text_waiting_list = I18nFormField( mail_text_waiting_list = I18nFormField(
label=_("Text"), label=_("Text"),
required=False, required=False,
widget=I18nTextarea, widget=I18nTextarea,
) )
mail_subject_order_canceled = I18nFormField(
label=_("Subject"),
required=False,
widget=I18nTextInput,
)
mail_text_order_canceled = I18nFormField( mail_text_order_canceled = I18nFormField(
label=_("Text"), label=_("Text"),
required=False, required=False,
@@ -1020,6 +1093,11 @@ class MailSettingsForm(SettingsForm):
required=False, required=False,
widget=I18nTextarea, widget=I18nTextarea,
) )
mail_subject_download_reminder = I18nFormField(
label=_("Subject sent to order contact address"),
required=False,
widget=I18nTextInput,
)
mail_text_download_reminder = I18nFormField( mail_text_download_reminder = I18nFormField(
label=_("Text sent to order contact address"), label=_("Text sent to order contact address"),
required=False, required=False,
@@ -1031,6 +1109,11 @@ class MailSettingsForm(SettingsForm):
'tickets, the following email will be sent out to the attendees.'), 'tickets, the following email will be sent out to the attendees.'),
required=False, required=False,
) )
mail_subject_download_reminder_attendee = I18nFormField(
label=_("Subject sent to attendees"),
required=False,
widget=I18nTextInput,
)
mail_text_download_reminder_attendee = I18nFormField( mail_text_download_reminder_attendee = I18nFormField(
label=_("Text sent to attendees"), label=_("Text sent to attendees"),
required=False, required=False,
@@ -1043,50 +1126,90 @@ class MailSettingsForm(SettingsForm):
help_text=_("This email will be sent out this many days before the order event starts. If the " help_text=_("This email will be sent out this many days before the order event starts. If the "
"field is empty, the mail will never be sent.") "field is empty, the mail will never be sent.")
) )
mail_subject_order_placed_require_approval = I18nFormField(
label=_("Subject for received order"),
required=False,
widget=I18nTextInput,
)
mail_text_order_placed_require_approval = I18nFormField( mail_text_order_placed_require_approval = I18nFormField(
label=_("Received order"), label=_("Text for received order"),
required=False, required=False,
widget=I18nTextarea, widget=I18nTextarea,
) )
mail_subject_order_approved = I18nFormField(
label=_("Subject for approved order"),
required=False,
widget=I18nTextInput,
)
mail_text_order_approved = I18nFormField( mail_text_order_approved = I18nFormField(
label=_("Approved order"), label=_("Text for approved order"),
required=False, required=False,
widget=I18nTextarea, widget=I18nTextarea,
help_text=_("This will only be sent out for non-free orders. Free orders will receive the free order " help_text=_("This will only be sent out for non-free orders. Free orders will receive the free order "
"template from below instead."), "template from below instead."),
) )
mail_subject_order_approved_free = I18nFormField(
label=_("Subject for approved free order"),
required=False,
widget=I18nTextInput,
)
mail_text_order_approved_free = I18nFormField( mail_text_order_approved_free = I18nFormField(
label=_("Approved free order"), label=_("Text for approved free order"),
required=False, required=False,
widget=I18nTextarea, widget=I18nTextarea,
help_text=_("This will only be sent out for free orders. Non-free orders will receive the non-free order " help_text=_("This will only be sent out for free orders. Non-free orders will receive the non-free order "
"template from above instead."), "template from above instead."),
) )
mail_subject_order_denied = I18nFormField(
label=_("Subject for denied order"),
required=False,
widget=I18nTextInput,
)
mail_text_order_denied = I18nFormField( mail_text_order_denied = I18nFormField(
label=_("Denied order"), label=_("Text for denied order"),
required=False, required=False,
widget=I18nTextarea, widget=I18nTextarea,
) )
base_context = { base_context = {
'mail_text_order_placed': ['event', 'order', 'payment'], 'mail_text_order_placed': ['event', 'order', 'payment'],
'mail_subject_order_placed': ['event', 'order', 'payment'],
'mail_text_order_placed_attendee': ['event', 'order', 'position'], 'mail_text_order_placed_attendee': ['event', 'order', 'position'],
'mail_subject_order_placed_attendee': ['event', 'order', 'position'],
'mail_text_order_placed_require_approval': ['event', 'order'], 'mail_text_order_placed_require_approval': ['event', 'order'],
'mail_subject_order_placed_require_approval': ['event', 'order'],
'mail_text_order_approved': ['event', 'order'], 'mail_text_order_approved': ['event', 'order'],
'mail_subject_order_approved': ['event', 'order'],
'mail_text_order_approved_free': ['event', 'order'], 'mail_text_order_approved_free': ['event', 'order'],
'mail_subject_order_approved_free': ['event', 'order'],
'mail_text_order_denied': ['event', 'order', 'comment'], 'mail_text_order_denied': ['event', 'order', 'comment'],
'mail_subject_order_denied': ['event', 'order', 'comment'],
'mail_text_order_paid': ['event', 'order', 'payment_info'], 'mail_text_order_paid': ['event', 'order', 'payment_info'],
'mail_subject_order_paid': ['event', 'order', 'payment_info'],
'mail_text_order_paid_attendee': ['event', 'order', 'position'], 'mail_text_order_paid_attendee': ['event', 'order', 'position'],
'mail_subject_order_paid_attendee': ['event', 'order', 'position'],
'mail_text_order_free': ['event', 'order'], 'mail_text_order_free': ['event', 'order'],
'mail_subject_order_free': ['event', 'order'],
'mail_text_order_free_attendee': ['event', 'order', 'position'], 'mail_text_order_free_attendee': ['event', 'order', 'position'],
'mail_subject_order_free_attendee': ['event', 'order', 'position'],
'mail_text_order_changed': ['event', 'order'], 'mail_text_order_changed': ['event', 'order'],
'mail_subject_order_changed': ['event', 'order'],
'mail_text_order_canceled': ['event', 'order', 'comment'], 'mail_text_order_canceled': ['event', 'order', 'comment'],
'mail_subject_order_canceled': ['event', 'order', 'comment'],
'mail_text_order_expire_warning': ['event', 'order'], 'mail_text_order_expire_warning': ['event', 'order'],
'mail_subject_order_expire_warning': ['event', 'order'],
'mail_subject_order_pending_warning': ['event', 'order'],
'mail_text_order_custom_mail': ['event', 'order'], 'mail_text_order_custom_mail': ['event', 'order'],
'mail_text_download_reminder': ['event', 'order'], 'mail_text_download_reminder': ['event', 'order'],
'mail_subject_download_reminder': ['event', 'order'],
'mail_text_download_reminder_attendee': ['event', 'order', 'position'], 'mail_text_download_reminder_attendee': ['event', 'order', 'position'],
'mail_subject_download_reminder_attendee': ['event', 'order', 'position'],
'mail_text_resend_link': ['event', 'order'], 'mail_text_resend_link': ['event', 'order'],
'mail_subject_resend_link': ['event', 'order'],
'mail_subject_resend_link_attendee': ['event', 'order'],
'mail_text_waiting_list': ['event', 'waiting_list_entry'], 'mail_text_waiting_list': ['event', 'waiting_list_entry'],
'mail_subject_waiting_list': ['event', 'waiting_list_entry'],
'mail_text_resend_all_links': ['event', 'orders'], 'mail_text_resend_all_links': ['event', 'orders'],
'mail_subject_resend_all_links': ['event', 'orders'],
'mail_attach_ical_description': ['event', 'event_or_subevent'], 'mail_attach_ical_description': ['event', 'event_or_subevent'],
} }
+5 -3
View File
@@ -806,7 +806,8 @@ class OrderSearchFilterForm(OrderFilterForm):
# We ignore superuser permissions here. This is intentional we do not want to show super # We ignore superuser permissions here. This is intentional we do not want to show super
# users a form with all meta properties ever assigned. # users a form with all meta properties ever assigned.
return EventMetaProperty.objects.filter( return EventMetaProperty.objects.filter(
organizer_id__in=self.request.user.teams.values_list('organizer', flat=True) organizer_id__in=self.request.user.teams.values_list('organizer', flat=True),
filter_allowed=True,
) )
@@ -1545,12 +1546,13 @@ class EventFilterForm(FilterForm):
@cached_property @cached_property
def meta_properties(self): def meta_properties(self):
if self.organizer: if self.organizer:
return self.organizer.meta_properties.all() return self.organizer.meta_properties.filter(filter_allowed=True)
else: else:
# We ignore superuser permissions here. This is intentional we do not want to show super # We ignore superuser permissions here. This is intentional we do not want to show super
# users a form with all meta properties ever assigned. # users a form with all meta properties ever assigned.
return EventMetaProperty.objects.filter( return EventMetaProperty.objects.filter(
organizer_id__in=self.request.user.teams.values_list('organizer', flat=True) organizer_id__in=self.request.user.teams.values_list('organizer', flat=True),
filter_allowed=True,
) )
+12 -5
View File
@@ -38,7 +38,9 @@ from decimal import Decimal
from urllib.parse import urlencode from urllib.parse import urlencode
from django import forms from django import forms
from django.conf import settings
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.core.files.uploadedfile import UploadedFile
from django.db.models import Max from django.db.models import Max
from django.forms.formsets import DELETION_FIELD_NAME from django.forms.formsets import DELETION_FIELD_NAME
from django.urls import reverse from django.urls import reverse
@@ -61,7 +63,8 @@ from pretix.base.models import (
from pretix.base.models.items import ItemAddOn, ItemBundle, ItemMetaValue from pretix.base.models.items import ItemAddOn, ItemBundle, ItemMetaValue
from pretix.base.signals import item_copy_data from pretix.base.signals import item_copy_data
from pretix.control.forms import ( from pretix.control.forms import (
ItemMultipleChoiceField, SplitDateTimeField, SplitDateTimePickerWidget, ItemMultipleChoiceField, SizeValidationMixin, SplitDateTimeField,
SplitDateTimePickerWidget,
) )
from pretix.control.forms.widgets import Select2 from pretix.control.forms.widgets import Select2
from pretix.helpers.models import modelcopy from pretix.helpers.models import modelcopy
@@ -584,6 +587,14 @@ class ItemUpdateForm(I18nModelForm):
) )
return d return d
def clean_picture(self):
value = self.cleaned_data.get('picture')
if isinstance(value, UploadedFile) and value.size > settings.FILE_UPLOAD_MAX_SIZE_IMAGE:
raise forms.ValidationError(_("Please do not upload files larger than {size}!").format(
size=SizeValidationMixin._sizeof_fmt(settings.FILE_UPLOAD_MAX_SIZE_IMAGE)
))
return value
class Meta: class Meta:
model = Item model = Item
localized_fields = '__all__' localized_fields = '__all__'
@@ -768,10 +779,6 @@ class ItemAddOnsFormSet(I18nFormSet):
if self._should_delete_form(form): if self._should_delete_form(form):
# This form is going to be deleted so any of its errors # This form is going to be deleted so any of its errors
# should not cause the entire formset to be invalid. # should not cause the entire formset to be invalid.
try:
categories.remove(form.cleaned_data['addon_category'].pk)
except KeyError:
pass
continue continue
if 'addon_category' in form.cleaned_data: if 'addon_category' in form.cleaned_data:
+9 -13
View File
@@ -158,7 +158,7 @@ class CancelForm(ForceQuotaConfirmationForm):
localize=True, localize=True,
label=_('Keep a cancellation fee of'), label=_('Keep a cancellation fee of'),
help_text=_('If you keep a fee, all positions within this order will be canceled and the order will be reduced ' help_text=_('If you keep a fee, all positions within this order will be canceled and the order will be reduced '
'to a paid cancellation fee. Payment and shipping fees will be canceled as well, so include them ' 'to a cancellation fee. Payment and shipping fees will be canceled as well, so include them '
'in your cancellation fee if you want to keep them. Please always enter a gross value, ' 'in your cancellation fee if you want to keep them. Please always enter a gross value, '
'tax will be calculated automatically.'), 'tax will be calculated automatically.'),
) )
@@ -176,23 +176,19 @@ class CancelForm(ForceQuotaConfirmationForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
prs = self.instance.payment_refund_sum change_decimal_field(self.fields['cancellation_fee'], self.instance.event.currency)
if prs > 0: self.fields['cancellation_fee'].widget.attrs['placeholder'] = floatformat(
change_decimal_field(self.fields['cancellation_fee'], self.instance.event.currency) Decimal('0.00'),
self.fields['cancellation_fee'].widget.attrs['placeholder'] = floatformat( settings.CURRENCY_PLACES.get(self.instance.event.currency, 2)
Decimal('0.00'), )
settings.CURRENCY_PLACES.get(self.instance.event.currency, 2) self.fields['cancellation_fee'].max_value = self.instance.total
)
self.fields['cancellation_fee'].max_value = prs
else:
del self.fields['cancellation_fee']
if not self.instance.invoices.exists(): if not self.instance.invoices.exists():
del self.fields['cancel_invoice'] del self.fields['cancel_invoice']
def clean_cancellation_fee(self): def clean_cancellation_fee(self):
val = self.cleaned_data['cancellation_fee'] or Decimal('0.00') val = self.cleaned_data['cancellation_fee'] or Decimal('0.00')
if val > self.instance.payment_refund_sum: if val > self.instance.total:
raise ValidationError(_('The cancellation fee cannot be higher than the payment credit of this order.')) raise ValidationError(_('The cancellation fee cannot be higher than the total amount of this order.'))
return val return val
+22 -2
View File
@@ -45,7 +45,9 @@ from django.utils.crypto import get_random_string
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from django.utils.translation import gettext_lazy as _, pgettext_lazy from django.utils.translation import gettext_lazy as _, pgettext_lazy
from django_scopes.forms import SafeModelMultipleChoiceField from django_scopes.forms import SafeModelMultipleChoiceField
from i18nfield.forms import I18nFormField, I18nFormSetMixin, I18nTextarea from i18nfield.forms import (
I18nFormField, I18nFormSetMixin, I18nTextarea, I18nTextInput,
)
from phonenumber_field.formfields import PhoneNumberField from phonenumber_field.formfields import PhoneNumberField
from pytz import common_timezones from pytz import common_timezones
@@ -180,7 +182,7 @@ class OrganizerUpdateForm(OrganizerForm):
class EventMetaPropertyForm(forms.ModelForm): class EventMetaPropertyForm(forms.ModelForm):
class Meta: class Meta:
model = EventMetaProperty model = EventMetaProperty
fields = ['name', 'default', 'required', 'protected', 'allowed_values'] fields = ['name', 'default', 'required', 'protected', 'allowed_values', 'filter_allowed']
widgets = { widgets = {
'default': forms.TextInput() 'default': forms.TextInput()
} }
@@ -457,16 +459,31 @@ class MailSettingsForm(SettingsForm):
}} }}
) )
mail_subject_customer_registration = I18nFormField(
label=_("Subject"),
required=False,
widget=I18nTextInput,
)
mail_text_customer_registration = I18nFormField( mail_text_customer_registration = I18nFormField(
label=_("Text"), label=_("Text"),
required=False, required=False,
widget=I18nTextarea, widget=I18nTextarea,
) )
mail_subject_customer_email_change = I18nFormField(
label=_("Subject"),
required=False,
widget=I18nTextInput,
)
mail_text_customer_email_change = I18nFormField( mail_text_customer_email_change = I18nFormField(
label=_("Text"), label=_("Text"),
required=False, required=False,
widget=I18nTextarea, widget=I18nTextarea,
) )
mail_subject_customer_reset = I18nFormField(
label=_("Subject"),
required=False,
widget=I18nTextInput,
)
mail_text_customer_reset = I18nFormField( mail_text_customer_reset = I18nFormField(
label=_("Text"), label=_("Text"),
required=False, required=False,
@@ -475,8 +492,11 @@ class MailSettingsForm(SettingsForm):
base_context = { base_context = {
'mail_text_customer_registration': ['customer', 'url'], 'mail_text_customer_registration': ['customer', 'url'],
'mail_subject_customer_registration': ['customer', 'url'],
'mail_text_customer_email_change': ['customer', 'url'], 'mail_text_customer_email_change': ['customer', 'url'],
'mail_subject_customer_email_change': ['customer', 'url'],
'mail_text_customer_reset': ['customer', 'url'], 'mail_text_customer_reset': ['customer', 'url'],
'mail_subject_customer_reset': ['customer', 'url'],
} }
def _get_sample_context(self, base_parameters): def _get_sample_context(self, base_parameters):
+7 -4
View File
@@ -72,7 +72,7 @@ class VoucherForm(I18nModelForm):
localized_fields = '__all__' localized_fields = '__all__'
fields = [ fields = [
'code', 'valid_until', 'block_quota', 'allow_ignore_quota', 'value', 'tag', 'code', 'valid_until', 'block_quota', 'allow_ignore_quota', 'value', 'tag',
'comment', 'max_usages', 'price_mode', 'subevent', 'show_hidden_items', 'budget' 'comment', 'max_usages', 'min_usages', 'price_mode', 'subevent', 'show_hidden_items', 'budget'
] ]
field_classes = { field_classes = {
'valid_until': SplitDateTimeField, 'valid_until': SplitDateTimeField,
@@ -308,7 +308,7 @@ class VoucherBulkForm(VoucherForm):
localized_fields = '__all__' localized_fields = '__all__'
fields = [ fields = [
'valid_until', 'block_quota', 'allow_ignore_quota', 'value', 'tag', 'comment', 'valid_until', 'block_quota', 'allow_ignore_quota', 'value', 'tag', 'comment',
'max_usages', 'price_mode', 'subevent', 'show_hidden_items', 'budget' 'max_usages', 'min_usages', 'price_mode', 'subevent', 'show_hidden_items', 'budget'
] ]
field_classes = { field_classes = {
'valid_until': SplitDateTimeField, 'valid_until': SplitDateTimeField,
@@ -345,8 +345,11 @@ class VoucherBulkForm(VoucherForm):
if ',' in raw or ';' in raw: if ',' in raw or ';' in raw:
if '@' in r[0]: if '@' in r[0]:
raise ValidationError(_('CSV input needs to contain a header row in the first line.')) raise ValidationError(_('CSV input needs to contain a header row in the first line.'))
dialect = csv.Sniffer().sniff(raw[:1024]) try:
reader = csv.DictReader(StringIO(raw), dialect=dialect) dialect = csv.Sniffer().sniff(raw[:1024])
reader = csv.DictReader(StringIO(raw), dialect=dialect)
except csv.Error as e:
raise ValidationError(_('CSV parsing failed: {error}.').format(error=str(e)))
if 'email' not in reader.fieldnames: if 'email' not in reader.fieldnames:
raise ValidationError(_('CSV input needs to contain a field with the header "{header}".').format(header="email")) raise ValidationError(_('CSV input needs to contain a field with the header "{header}".').format(header="email"))
unknown_fields = [f for f in reader.fieldnames if f not in ('email', 'name', 'tag', 'number')] unknown_fields = [f for f in reader.fieldnames if f not in ('email', 'name', 'tag', 'number')]
@@ -11,7 +11,7 @@
{% trans "You configured your account to require authentication with a second medium, e.g. your phone. Please enter your verification code here:" %} {% trans "You configured your account to require authentication with a second medium, e.g. your phone. Please enter your verification code here:" %}
</p> </p>
<div class="form-group"> <div class="form-group">
<input class="form-control" name="token" placeholder="{% trans "Token" %}" <input class="form-control" name="token" placeholder="{% trans "Token" %}" autocomplete="one-time-code"
type="text" required="required" autofocus="autofocus" id="webauthn-response"> type="text" required="required" autofocus="autofocus" id="webauthn-response">
</div> </div>
<div class="sr-only alert alert-danger" id="webauthn-error"> <div class="sr-only alert alert-danger" id="webauthn-error">
@@ -116,8 +116,12 @@
</form> </form>
{{ items|json_script:"items" }} {{ items|json_script:"items" }}
{% compress js %} {% if DEBUG %}
<script type="text/javascript" src="{% static "vuejs/vue.js" %}"></script> <script type="text/javascript" src="{% static "vuejs/vue.js" %}"></script>
{% else %}
<script type="text/javascript" src="{% static "vuejs/vue.min.js" %}"></script>
{% endif %}
{% compress js %}
<script type="text/javascript" src="{% static "d3/d3.v6.js" %}"></script> <script type="text/javascript" src="{% static "d3/d3.v6.js" %}"></script>
<script type="text/javascript" src="{% static "d3/d3-color.v2.js" %}"></script> <script type="text/javascript" src="{% static "d3/d3-color.v2.js" %}"></script>
<script type="text/javascript" src="{% static "d3/d3-dispatch.v2.js" %}"></script> <script type="text/javascript" src="{% static "d3/d3-dispatch.v2.js" %}"></script>
@@ -128,6 +132,8 @@
<script type="text/javascript" src="{% static "d3/d3-transition.v2.js" %}"></script> <script type="text/javascript" src="{% static "d3/d3-transition.v2.js" %}"></script>
<script type="text/javascript" src="{% static "d3/d3-drag.v2.js" %}"></script> <script type="text/javascript" src="{% static "d3/d3-drag.v2.js" %}"></script>
<script type="text/javascript" src="{% static "d3/d3-zoom.v2.js" %}"></script> <script type="text/javascript" src="{% static "d3/d3-zoom.v2.js" %}"></script>
{% endcompress %}
{% compress js %}
<script type="text/javascript" src="{% static "pretixcontrol/js/ui/checkinrules/jsonlogic-boolalg.js" %}"></script> <script type="text/javascript" src="{% static "pretixcontrol/js/ui/checkinrules/jsonlogic-boolalg.js" %}"></script>
<script type="text/vue" src="{% static 'pretixcontrol/js/ui/checkinrules/datetimefield.vue' %}"></script> <script type="text/vue" src="{% static 'pretixcontrol/js/ui/checkinrules/datetimefield.vue' %}"></script>
<script type="text/vue" src="{% static 'pretixcontrol/js/ui/checkinrules/timefield.vue' %}"></script> <script type="text/vue" src="{% static 'pretixcontrol/js/ui/checkinrules/timefield.vue' %}"></script>
@@ -11,6 +11,9 @@
<legend>{% trans "Unpaid or free orders" %}</legend> <legend>{% trans "Unpaid or free orders" %}</legend>
{% bootstrap_field form.cancel_allow_user layout="control" %} {% bootstrap_field form.cancel_allow_user layout="control" %}
{% bootstrap_field form.cancel_allow_user_until layout="control" %} {% bootstrap_field form.cancel_allow_user_until layout="control" %}
{% bootstrap_field form.cancel_allow_user_unpaid_keep layout="control" %}
{% bootstrap_field form.cancel_allow_user_unpaid_keep_percentage layout="control" %}
{% bootstrap_field form.cancel_allow_user_unpaid_keep_fees layout="control" %}
</fieldset> </fieldset>
<fieldset> <fieldset>
<legend>{% trans "Paid orders" %}</legend> <legend>{% trans "Paid orders" %}</legend>
@@ -88,37 +88,37 @@
<h4>{% trans "Text" %}</h4> <h4>{% trans "Text" %}</h4>
<div class="panel-group" id="questions_group"> <div class="panel-group" id="questions_group">
{% blocktrans asvar title_placed_order %}Placed order{% endblocktrans %} {% blocktrans asvar title_placed_order %}Placed order{% endblocktrans %}
{% include "pretixcontrol/event/mail_settings_fragment.html" with pid="order_placed" title=title_placed_order items="mail_text_order_placed,mail_send_order_placed_attendee,mail_text_order_placed_attendee" exclude="mail_send_order_placed_attendee" %} {% include "pretixcontrol/event/mail_settings_fragment.html" with pid="order_placed" title=title_placed_order items="mail_subject_order_placed,mail_text_order_placed,mail_send_order_placed_attendee,mail_subject_order_placed_attendee,mail_text_order_placed_attendee" exclude="mail_send_order_placed_attendee" %}
{% blocktrans asvar title_paid_order %}Paid order{% endblocktrans %} {% blocktrans asvar title_paid_order %}Paid order{% endblocktrans %}
{% include "pretixcontrol/event/mail_settings_fragment.html" with pid="order_paid" title=title_paid_order items="mail_text_order_paid,mail_send_order_paid_attendee,mail_text_order_paid_attendee" exclude="mail_send_order_paid_attendee" %} {% include "pretixcontrol/event/mail_settings_fragment.html" with pid="order_paid" title=title_paid_order items="mail_subject_order_paid,mail_text_order_paid,mail_send_order_paid_attendee,mail_subject_order_paid_attendee,mail_text_order_paid_attendee" exclude="mail_send_order_paid_attendee" %}
{% blocktrans asvar title_free_order %}Free order{% endblocktrans %} {% blocktrans asvar title_free_order %}Free order{% endblocktrans %}
{% include "pretixcontrol/event/mail_settings_fragment.html" with pid="order_free" title=title_free_order items="mail_text_order_free,mail_send_order_free_attendee,mail_text_order_free_attendee" exclude="mail_send_order_free_attendee" %} {% include "pretixcontrol/event/mail_settings_fragment.html" with pid="order_free" title=title_free_order items="mail_subject_order_free,mail_text_order_free,mail_send_order_free_attendee,mail_subject_order_free_attendee,mail_text_order_free_attendee" exclude="mail_send_order_free_attendee" %}
{% blocktrans asvar title_resend_link %}Resend link{% endblocktrans %} {% blocktrans asvar title_resend_link %}Resend link{% endblocktrans %}
{% include "pretixcontrol/event/mail_settings_fragment.html" with pid="resend_link" title=title_resend_link items="mail_text_resend_link,mail_text_resend_all_links" %} {% include "pretixcontrol/event/mail_settings_fragment.html" with pid="resend_link" title=title_resend_link items="mail_subject_resend_link,mail_subject_resend_link_attendee,mail_text_resend_link,mail_subject_resend_all_links,mail_text_resend_all_links" %}
{% blocktrans asvar title_order_changed %}Order changed{% endblocktrans %} {% blocktrans asvar title_order_changed %}Order changed{% endblocktrans %}
{% include "pretixcontrol/event/mail_settings_fragment.html" with pid="order_changed" title=title_order_changed items="mail_text_order_changed" %} {% include "pretixcontrol/event/mail_settings_fragment.html" with pid="order_changed" title=title_order_changed items="mail_subject_order_changed,mail_text_order_changed" %}
{% blocktrans asvar title_payment_reminder %}Payment reminder{% endblocktrans %} {% blocktrans asvar title_payment_reminder %}Payment reminder{% endblocktrans %}
{% include "pretixcontrol/event/mail_settings_fragment.html" with pid="order_expirew" title=title_payment_reminder items="mail_days_order_expire_warning,mail_text_order_expire_warning" exclude="mail_days_order_expire_warning" %} {% include "pretixcontrol/event/mail_settings_fragment.html" with pid="order_expirew" title=title_payment_reminder items="mail_days_order_expire_warning,mail_subject_order_expire_warning,mail_subject_order_pending_warning,mail_text_order_expire_warning" exclude="mail_days_order_expire_warning" %}
{% blocktrans asvar title_waiting_list_notification %}Waiting list notification{% endblocktrans %} {% blocktrans asvar title_waiting_list_notification %}Waiting list notification{% endblocktrans %}
{% include "pretixcontrol/event/mail_settings_fragment.html" with pid="waiting_list" title=title_waiting_list_notification items="mail_text_waiting_list" %} {% include "pretixcontrol/event/mail_settings_fragment.html" with pid="waiting_list" title=title_waiting_list_notification items="mail_subject_waiting_list,mail_text_waiting_list" %}
{% blocktrans asvar title_order_canceled %}Order canceled{% endblocktrans %} {% blocktrans asvar title_order_canceled %}Order canceled{% endblocktrans %}
{% include "pretixcontrol/event/mail_settings_fragment.html" with pid="order_canceled" title=title_order_canceled items="mail_text_order_canceled" %} {% include "pretixcontrol/event/mail_settings_fragment.html" with pid="order_canceled" title=title_order_canceled items="mail_subject_order_canceled,mail_text_order_canceled" %}
{% blocktrans asvar title_order_custom_mail %}Order custom mail{% endblocktrans %} {% blocktrans asvar title_order_custom_mail %}Order custom mail{% endblocktrans %}
{% include "pretixcontrol/event/mail_settings_fragment.html" with pid="custom_mail" title=title_order_custom_mail items="mail_text_order_custom_mail" %} {% include "pretixcontrol/event/mail_settings_fragment.html" with pid="custom_mail" title=title_order_custom_mail items="mail_text_order_custom_mail" %}
{% blocktrans asvar title_download_tickets_reminder %}Reminder to download tickets{% endblocktrans %} {% blocktrans asvar title_download_tickets_reminder %}Reminder to download tickets{% endblocktrans %}
{% include "pretixcontrol/event/mail_settings_fragment.html" with pid="ticket_reminder" title=title_download_tickets_reminder items="mail_days_download_reminder,mail_text_download_reminder,mail_send_download_reminder_attendee,mail_text_download_reminder_attendee,mail_sales_channel_download_reminder" exclude="mail_days_download_reminder,mail_send_download_reminder_attendee,mail_sales_channel_download_reminder" %} {% include "pretixcontrol/event/mail_settings_fragment.html" with pid="ticket_reminder" title=title_download_tickets_reminder items="mail_days_download_reminder,mail_subject_download_reminder,mail_text_download_reminder,mail_send_download_reminder_attendee,mail_subject_download_reminder_attendee,mail_text_download_reminder_attendee,mail_sales_channel_download_reminder" exclude="mail_days_download_reminder,mail_send_download_reminder_attendee,mail_sales_channel_download_reminder" %}
{% blocktrans asvar title_require_approval %}Order approval process{% endblocktrans %} {% blocktrans asvar title_require_approval %}Order approval process{% endblocktrans %}
{% include "pretixcontrol/event/mail_settings_fragment.html" with pid="ticket_reminder" title=title_require_approval items="mail_text_order_placed_require_approval,mail_text_order_approved,mail_text_order_approved_free,mail_text_order_denied" %} {% include "pretixcontrol/event/mail_settings_fragment.html" with pid="ticket_reminder" title=title_require_approval items="mail_subject_order_placed_require_approval,mail_text_order_placed_require_approval,mail_subject_order_approved,mail_text_order_approved,mail_subject_order_approved_free,mail_text_order_approved_free,mail_subject_order_denied,mail_text_order_denied" %}
</div> </div>
<h4>{% trans "Attachments" %}</h4> <h4>{% trans "Attachments" %}</h4>
{% bootstrap_field form.mail_attachment_new_order layout="control" %} {% bootstrap_field form.mail_attachment_new_order layout="control" %}
@@ -190,7 +190,13 @@
</dd> </dd>
{% if order.status == "n" %} {% if order.status == "n" %}
<dt>{% trans "Expiry date" %}</dt> <dt>{% trans "Expiry date" %}</dt>
<dd>{{ order.expires|date:"SHORT_DATETIME_FORMAT" }}</dd> <dd>
{{ order.expires|date:"SHORT_DATETIME_FORMAT" }}
{% if has_cancellation_fee and request.event.settings.payment_term_expire_automatically %}
<span class="fa fa-warning text-danger" data-toggle="tooltip"
title="{% trans "This order will not expire automatically as it has an open cancellation fee." %}"></span>
{% endif %}
</dd>
{% endif %} {% endif %}
{% if request.organizer.settings.customer_accounts %} {% if request.organizer.settings.customer_accounts %}
<dt>{% trans "Customer account" %}</dt> <dt>{% trans "Customer account" %}</dt>
@@ -58,13 +58,13 @@
<legend>{% trans "E-mail content" %}</legend> <legend>{% trans "E-mail content" %}</legend>
<div class="panel-group" id="questions_group"> <div class="panel-group" id="questions_group">
{% blocktrans asvar title_customer_registration %}Customer account registration{% endblocktrans %} {% blocktrans asvar title_customer_registration %}Customer account registration{% endblocktrans %}
{% include "pretixcontrol/event/mail_settings_fragment.html" with pid="customer_registration" title=title_customer_registration items="mail_text_customer_registration" %} {% include "pretixcontrol/event/mail_settings_fragment.html" with pid="customer_registration" title=title_customer_registration items="mail_subject_customer_registration,mail_text_customer_registration" %}
{% blocktrans asvar title_email_change %}Customer account email change{% endblocktrans %} {% blocktrans asvar title_email_change %}Customer account email change{% endblocktrans %}
{% include "pretixcontrol/event/mail_settings_fragment.html" with pid="email_change" title=title_email_change items="mail_text_customer_email_change" %} {% include "pretixcontrol/event/mail_settings_fragment.html" with pid="email_change" title=title_email_change items="mail_subject_customer_email_change,mail_text_customer_email_change" %}
{% blocktrans asvar title_reset %}Customer account password reset{% endblocktrans %} {% blocktrans asvar title_reset %}Customer account password reset{% endblocktrans %}
{% include "pretixcontrol/event/mail_settings_fragment.html" with pid="reset" title=title_reset items="mail_text_customer_reset" %} {% include "pretixcontrol/event/mail_settings_fragment.html" with pid="reset" title=title_reset items="mail_subject_customer_reset,mail_text_customer_reset" %}
</div> </div>
</fieldset> </fieldset>
</div> </div>
@@ -73,6 +73,7 @@
<legend>{% trans "Advanced settings" %}</legend> <legend>{% trans "Advanced settings" %}</legend>
{% bootstrap_field form.block_quota layout="control" %} {% bootstrap_field form.block_quota layout="control" %}
{% bootstrap_field form.allow_ignore_quota layout="control" %} {% bootstrap_field form.allow_ignore_quota layout="control" %}
{% bootstrap_field form.min_usages layout="control" %}
{% bootstrap_field form.budget addon_after=request.event.currency layout="control" %} {% bootstrap_field form.budget addon_after=request.event.currency layout="control" %}
{% bootstrap_field form.tag layout="control" %} {% bootstrap_field form.tag layout="control" %}
{% bootstrap_field form.comment layout="control" %} {% bootstrap_field form.comment layout="control" %}
@@ -85,6 +85,7 @@
<legend>{% trans "Advanced settings" %}</legend> <legend>{% trans "Advanced settings" %}</legend>
{% bootstrap_field form.block_quota layout="control" %} {% bootstrap_field form.block_quota layout="control" %}
{% bootstrap_field form.allow_ignore_quota layout="control" %} {% bootstrap_field form.allow_ignore_quota layout="control" %}
{% bootstrap_field form.min_usages layout="control" %}
{% bootstrap_field form.budget addon_after=request.event.currency layout="control" %} {% bootstrap_field form.budget addon_after=request.event.currency layout="control" %}
{% bootstrap_field form.tag layout="control" %} {% bootstrap_field form.tag layout="control" %}
{% bootstrap_field form.comment layout="control" %} {% bootstrap_field form.comment layout="control" %}
+6 -5
View File
@@ -61,6 +61,7 @@ from pretix.base.forms.auth import (
) )
from pretix.base.models import TeamInvite, U2FDevice, User, WebAuthnDevice from pretix.base.models import TeamInvite, U2FDevice, User, WebAuthnDevice
from pretix.base.services.mail import SendMailException from pretix.base.services.mail import SendMailException
from pretix.helpers.http import redirect_to_url
from pretix.helpers.webauthn import generate_challenge from pretix.helpers.webauthn import generate_challenge
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -81,7 +82,7 @@ def process_login(request, user, keep_logged_in):
twofa_url = reverse('control:auth.login.2fa') twofa_url = reverse('control:auth.login.2fa')
if next_url and url_has_allowed_host_and_scheme(next_url, allowed_hosts=None): if next_url and url_has_allowed_host_and_scheme(next_url, allowed_hosts=None):
twofa_url += '?next=' + quote(next_url) twofa_url += '?next=' + quote(next_url)
return redirect(twofa_url) return redirect_to_url(twofa_url)
else: else:
auth_login(request, user) auth_login(request, user)
request.session['pretix_auth_login_time'] = int(time.time()) request.session['pretix_auth_login_time'] = int(time.time())
@@ -110,7 +111,7 @@ def login(request):
if request.user.is_authenticated: if request.user.is_authenticated:
next_url = backend.get_next_url(request) or 'control:index' next_url = backend.get_next_url(request) or 'control:index'
if next_url and url_has_allowed_host_and_scheme(next_url, allowed_hosts=None): if next_url and url_has_allowed_host_and_scheme(next_url, allowed_hosts=None):
return redirect(next_url) return redirect_to_url(next_url)
return redirect(reverse('control:index')) return redirect(reverse('control:index'))
if request.method == 'POST': if request.method == 'POST':
form = LoginForm(backend=backend, data=request.POST, request=request) form = LoginForm(backend=backend, data=request.POST, request=request)
@@ -136,8 +137,8 @@ def logout(request):
if 'next' in request.GET and url_has_allowed_host_and_scheme(request.GET.get('next'), allowed_hosts=None): if 'next' in request.GET and url_has_allowed_host_and_scheme(request.GET.get('next'), allowed_hosts=None):
next += '?next=' + quote(request.GET.get('next')) next += '?next=' + quote(request.GET.get('next'))
if 'back' in request.GET and url_has_allowed_host_and_scheme(request.GET.get('back'), allowed_hosts=None): if 'back' in request.GET and url_has_allowed_host_and_scheme(request.GET.get('back'), allowed_hosts=None):
return redirect(request.GET.get('back')) return redirect_to_url(request.GET.get('back'))
return redirect(next) return redirect_to_url(next)
def register(request): def register(request):
@@ -443,7 +444,7 @@ class Login2FAView(TemplateView):
del request.session['pretix_auth_2fa_user'] del request.session['pretix_auth_2fa_user']
del request.session['pretix_auth_2fa_time'] del request.session['pretix_auth_2fa_time']
if "next" in request.GET and url_has_allowed_host_and_scheme(request.GET.get("next"), allowed_hosts=None): if "next" in request.GET and url_has_allowed_host_and_scheme(request.GET.get("next"), allowed_hosts=None):
return redirect(request.GET.get("next")) return redirect_to_url(request.GET.get("next"))
return redirect(reverse('control:index')) return redirect(reverse('control:index'))
else: else:
messages.error(request, _('Invalid code, please try again.')) messages.error(request, _('Invalid code, please try again.'))
+9 -5
View File
@@ -41,6 +41,7 @@ from decimal import Decimal
from itertools import groupby from itertools import groupby
from urllib.parse import urlsplit from urllib.parse import urlsplit
import bleach
from django.conf import settings from django.conf import settings
from django.contrib import messages from django.contrib import messages
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
@@ -386,7 +387,7 @@ class EventPlugins(EventSettingsViewMixin, EventPermissionRequiredMixin, Templat
if key.startswith("plugin:"): if key.startswith("plugin:"):
module = key.split(":")[1] module = key.split(":")[1]
if value == "enable" and module in plugins_available: if value == "enable" and module in plugins_available:
if getattr(plugins_available[module], 'restricted', False): if getattr(plugins_available[module].app, 'restricted', False):
if module not in request.event.settings.allowed_restricted_plugins: if module not in request.event.settings.allowed_restricted_plugins:
continue continue
@@ -723,7 +724,7 @@ class MailSettingsPreview(EventPermissionRequiredMixin, View):
if preview_item not in MailSettingsForm.base_context: if preview_item not in MailSettingsForm.base_context:
return HttpResponseBadRequest(_('invalid item')) return HttpResponseBadRequest(_('invalid item'))
regex = r"^" + re.escape(preview_item) + r"_(?P<idx>[\d+])$" regex = r"^" + re.escape(preview_item) + r"_(?P<idx>[\d]+)$"
msgs = {} msgs = {}
for k, v in request.POST.items(): for k, v in request.POST.items():
# only accept allowed fields # only accept allowed fields
@@ -732,9 +733,12 @@ class MailSettingsPreview(EventPermissionRequiredMixin, View):
idx = matched.group('idx') idx = matched.group('idx')
if idx in self.supported_locale: if idx in self.supported_locale:
with language(self.supported_locale[idx], self.request.event.settings.region): with language(self.supported_locale[idx], self.request.event.settings.region):
msgs[self.supported_locale[idx]] = markdown_compile_email( if k.startswith('mail_subject_'):
v.format_map(self.placeholders(preview_item)) msgs[self.supported_locale[idx]] = bleach.clean(v).format_map(self.placeholders(preview_item))
) else:
msgs[self.supported_locale[idx]] = markdown_compile_email(
v.format_map(self.placeholders(preview_item))
)
return JsonResponse({ return JsonResponse({
'item': preview_item, 'item': preview_item,
+10 -1
View File
@@ -32,6 +32,7 @@ from django.utils.translation import gettext_lazy as _
from django.views.generic import TemplateView from django.views.generic import TemplateView
from pretix.base import email from pretix.base import email
from pretix.base.forms import SECRET_REDACTED
from pretix.base.models import Event from pretix.base.models import Event
from pretix.base.services.mail import mail from pretix.base.services.mail import mail
from pretix.control.forms.filter import OrganizerFilterForm from pretix.control.forms.filter import OrganizerFilterForm
@@ -169,6 +170,13 @@ class MailSettingsSetupView(TemplateView):
) )
if allow_save: if allow_save:
self.object.settings.smtp_use_custom = False
del self.object.settings.smtp_host
del self.object.settings.smtp_port
del self.object.settings.smtp_username
del self.object.settings.smtp_password
del self.object.settings.smtp_use_tls
del self.object.settings.smtp_use_ssl
for k, v in self.simple_form.cleaned_data.items(): for k, v in self.simple_form.cleaned_data.items():
self.object.settings.set(k, v) self.object.settings.set(k, v)
self.log_action(self.simple_form.cleaned_data) self.log_action(self.simple_form.cleaned_data)
@@ -237,7 +245,8 @@ class MailSettingsSetupView(TemplateView):
if request.POST.get('state') == 'save': if request.POST.get('state') == 'save':
for k, v in self.smtp_form.cleaned_data.items(): for k, v in self.smtp_form.cleaned_data.items():
self.object.settings.set(k, v) if v != SECRET_REDACTED:
self.object.settings.set(k, v)
self.object.settings.smtp_use_custom = True self.object.settings.smtp_use_custom = True
self.log_action({**self.smtp_form.cleaned_data, 'smtp_use_custom': True}) self.log_action({**self.smtp_form.cleaned_data, 'smtp_use_custom': True})
messages.success(request, _('Your changes have been saved.')) messages.success(request, _('Your changes have been saved.'))
+2 -1
View File
@@ -276,7 +276,8 @@ class EventWizard(SafeSessionWizardView):
t.limit_events.add(event) t.limit_events.add(event)
elif event.organizer.settings.event_team_provisioning: elif event.organizer.settings.event_team_provisioning:
t = Team.objects.create( t = Team.objects.create(
organizer=event.organizer, name=_('Team {event}').format(event=event.name), organizer=event.organizer,
name=_('Team {event}').format(event=str(event.name)[:188] + "" if len(str(event.name)) > 190 else str(event.name)),
can_change_event_settings=True, can_change_items=True, can_change_event_settings=True, can_change_items=True,
can_view_orders=True, can_change_orders=True, can_view_vouchers=True, can_view_orders=True, can_change_orders=True, can_view_vouchers=True,
can_change_vouchers=True can_change_vouchers=True
+1
View File
@@ -293,6 +293,7 @@ class OrderDetail(OrderView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs) ctx = super().get_context_data(**kwargs)
ctx['items'] = self.get_items() ctx['items'] = self.get_items()
ctx['has_cancellation_fee'] = any(f.fee_type == OrderFee.FEE_TYPE_CANCELLATION for f in ctx['items']['fees'])
ctx['event'] = self.request.event ctx['event'] = self.request.event
ctx['payments'] = self.order.payments.order_by('-created') ctx['payments'] = self.order.payments.order_by('-created')
ctx['refunds'] = self.order.refunds.select_related('payment').order_by('-created') ctx['refunds'] = self.order.refunds.select_related('payment').order_by('-created')
+10 -6
View File
@@ -37,6 +37,7 @@ import re
from datetime import timedelta from datetime import timedelta
from decimal import Decimal from decimal import Decimal
import bleach
from django import forms from django import forms
from django.conf import settings from django.conf import settings
from django.contrib import messages from django.contrib import messages
@@ -204,7 +205,7 @@ class OrganizerDetail(OrganizerDetailViewMixin, OrganizerPermissionRequiredMixin
ctx = super().get_context_data(**kwargs) ctx = super().get_context_data(**kwargs)
ctx['filter_form'] = self.filter_form ctx['filter_form'] = self.filter_form
ctx['meta_fields'] = [ ctx['meta_fields'] = [
self.filter_form['meta_{}'.format(p.name)] for p in self.organizer.meta_properties.all() self.filter_form['meta_{}'.format(p.name)] for p in self.organizer.meta_properties.filter(filter_allowed=True)
] ]
return ctx return ctx
@@ -324,7 +325,7 @@ class MailSettingsPreview(OrganizerPermissionRequiredMixin, View):
if preview_item not in MailSettingsForm.base_context: if preview_item not in MailSettingsForm.base_context:
return HttpResponseBadRequest(_('invalid item')) return HttpResponseBadRequest(_('invalid item'))
regex = r"^" + re.escape(preview_item) + r"_(?P<idx>[\d+])$" regex = r"^" + re.escape(preview_item) + r"_(?P<idx>[\d]+)$"
msgs = {} msgs = {}
for k, v in request.POST.items(): for k, v in request.POST.items():
# only accept allowed fields # only accept allowed fields
@@ -333,9 +334,12 @@ class MailSettingsPreview(OrganizerPermissionRequiredMixin, View):
idx = matched.group('idx') idx = matched.group('idx')
if idx in self.supported_locale: if idx in self.supported_locale:
with language(self.supported_locale[idx], self.request.organizer.settings.region): with language(self.supported_locale[idx], self.request.organizer.settings.region):
msgs[self.supported_locale[idx]] = markdown_compile_email( if k.startswith('mail_subject_'):
v.format_map(self.placeholders(preview_item)) msgs[self.supported_locale[idx]] = bleach.clean(v).format_map(self.placeholders(preview_item))
) else:
msgs[self.supported_locale[idx]] = markdown_compile_email(
v.format_map(self.placeholders(preview_item))
)
return JsonResponse({ return JsonResponse({
'item': preview_item, 'item': preview_item,
@@ -2236,7 +2240,7 @@ class CustomerDetailView(OrganizerDetailViewMixin, OrganizerPermissionRequiredMi
) + '?id=' + self.customer.identifier + '&token=' + token ) + '?id=' + self.customer.identifier + '&token=' + token
mail( mail(
self.customer.email, self.customer.email,
_('Set a new password for your account at {organizer}').format(organizer=self.request.organizer.name), self.request.organizer.settings.mail_subject_customer_reset,
self.request.organizer.settings.mail_text_customer_reset, self.request.organizer.settings.mail_text_customer_reset,
ctx, ctx,
locale=self.customer.locale, locale=self.customer.locale,
+4 -3
View File
@@ -71,6 +71,7 @@ from pretix.control.permissions import (
AdministratorPermissionRequiredMixin, StaffMemberRequiredMixin, AdministratorPermissionRequiredMixin, StaffMemberRequiredMixin,
) )
from pretix.control.views.auth import get_u2f_appid from pretix.control.views.auth import get_u2f_appid
from pretix.helpers.http import redirect_to_url
from pretix.helpers.webauthn import generate_challenge, generate_ukey from pretix.helpers.webauthn import generate_challenge, generate_ukey
REAL_DEVICE_TYPES = (TOTPDevice, WebAuthnDevice, U2FDevice) REAL_DEVICE_TYPES = (TOTPDevice, WebAuthnDevice, U2FDevice)
@@ -138,7 +139,7 @@ class ReauthView(TemplateView):
request.session['pretix_auth_last_used'] = t request.session['pretix_auth_last_used'] = t
next_url = get_auth_backends()[request.user.auth_backend].get_next_url(request) next_url = get_auth_backends()[request.user.auth_backend].get_next_url(request)
if next_url and url_has_allowed_host_and_scheme(next_url, allowed_hosts=None): if next_url and url_has_allowed_host_and_scheme(next_url, allowed_hosts=None):
return redirect(next_url) return redirect_to_url(next_url)
return redirect(reverse('control:index')) return redirect(reverse('control:index'))
else: else:
messages.error(request, _('The password you entered was invalid, please try again.')) messages.error(request, _('The password you entered was invalid, please try again.'))
@@ -153,7 +154,7 @@ class ReauthView(TemplateView):
request.session['pretix_auth_login_time'] = t request.session['pretix_auth_login_time'] = t
request.session['pretix_auth_last_used'] = t request.session['pretix_auth_last_used'] = t
if next_url and url_has_allowed_host_and_scheme(next_url, allowed_hosts=None): if next_url and url_has_allowed_host_and_scheme(next_url, allowed_hosts=None):
return redirect(next_url) return redirect_to_url(next_url)
return redirect(reverse('control:index')) return redirect(reverse('control:index'))
return super().get(request, *args, **kwargs) return super().get(request, *args, **kwargs)
@@ -749,7 +750,7 @@ class StartStaffSession(StaffMemberRequiredMixin, RecentAuthenticationRequiredMi
) )
if "next" in request.GET and url_has_allowed_host_and_scheme(request.GET.get("next"), allowed_hosts=None): if "next" in request.GET and url_has_allowed_host_and_scheme(request.GET.get("next"), allowed_hosts=None):
return redirect(request.GET.get("next")) return redirect_to_url(request.GET.get("next"))
else: else:
return redirect(reverse("control:index")) return redirect(reverse("control:index"))
+1 -18
View File
@@ -23,8 +23,7 @@ import pyuca
from babel.core import Locale from babel.core import Locale
from django.core.cache import cache from django.core.cache import cache
from django.utils import translation from django.utils import translation
from django.utils.encoding import force_str from django_countries import Countries
from django_countries import Countries, CountryTuple
from django_countries.fields import CountryField from django_countries.fields import CountryField
from phonenumbers.data import _COUNTRY_CODE_TO_REGION_CODE from phonenumbers.data import _COUNTRY_CODE_TO_REGION_CODE
@@ -61,22 +60,6 @@ class CachedCountries(Countries):
cache.set(cache_key, val, 3600 * 24 * 30) cache.set(cache_key, val, 3600 * 24 * 30)
yield from val yield from val
def translate_pair(self, code: str, name=None):
# We need to temporarily override this function until
# https://github.com/SmileyChris/django-countries/issues/364
# is fixed
if name is None:
name = self.countries[code]
if isinstance(name, dict):
if "names" in name:
country_name: str = name["names"][0]
else:
country_name = name["name"]
else:
country_name = name
country_name = force_str(country_name)
return CountryTuple(code, country_name)
class FastCountryField(CountryField): class FastCountryField(CountryField):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
+8 -1
View File
@@ -20,7 +20,9 @@
# <https://www.gnu.org/licenses/>. # <https://www.gnu.org/licenses/>.
# #
from django.conf import settings from django.conf import settings
from django.http import StreamingHttpResponse from django.http import (
HttpResponsePermanentRedirect, HttpResponseRedirect, StreamingHttpResponse,
)
class ChunkBasedFileResponse(StreamingHttpResponse): class ChunkBasedFileResponse(StreamingHttpResponse):
@@ -40,3 +42,8 @@ def get_client_ip(request):
if x_forwarded_for: if x_forwarded_for:
ip = x_forwarded_for.split(',')[0] ip = x_forwarded_for.split(',')[0]
return ip return ip
def redirect_to_url(to, permanent=False):
redirect_class = HttpResponsePermanentRedirect if permanent else HttpResponseRedirect
return redirect_class(to)
+40
View File
@@ -21,9 +21,49 @@
# #
import logging import logging
import sentry_sdk
from django.core.signals import request_finished
from django.dispatch import receiver
try:
from asgiref.local import Local
except ImportError:
from threading import local as Local
from django.conf import settings from django.conf import settings
class AdminExistsFilter(logging.Filter): class AdminExistsFilter(logging.Filter):
def filter(self, record): def filter(self, record):
return not settings.DEBUG and len(settings.ADMINS) > 0 return not settings.DEBUG and len(settings.ADMINS) > 0
local = Local()
class RequestIdFilter(logging.Filter):
def filter(self, record):
record.request_id = getattr(local, 'request_id', None)
return True
class RequestIdMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
if settings.REQUEST_ID_HEADER and settings.REQUEST_ID_HEADER in request.headers:
local.request_id = request.request_id = request.headers[settings.REQUEST_ID_HEADER]
if settings.SENTRY_ENABLED:
sentry_sdk.set_tag("request_id", request.request_id)
else:
local.request_id = request.request_id = None
return self.get_response(request)
@receiver(request_finished)
def on_request_finished(sender, **kwargs):
# not part of middleware, since things could be logged after the middleware stack is finished
local.request_id = None
@@ -0,0 +1,18 @@
# Generated by Django 3.2.16 on 2022-11-21 17:22
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('pretixhelpers', '0002_auto_20180320_1219'),
]
operations = [
migrations.AddField(
model_name='thumbnail',
name='created',
field=models.DateTimeField(auto_now_add=True, null=True),
),
]
+1
View File
@@ -29,6 +29,7 @@ class Thumbnail(models.Model):
source = models.CharField(max_length=255) source = models.CharField(max_length=255)
size = models.CharField(max_length=255) size = models.CharField(max_length=255)
thumb = models.FileField(upload_to='pub/thumbs/', max_length=255) thumb = models.FileField(upload_to='pub/thumbs/', max_length=255)
created = models.DateTimeField(auto_now_add=True, null=True)
class Meta: class Meta:
unique_together = (('source', 'size'),) unique_together = (('source', 'size'),)
File diff suppressed because it is too large Load Diff
+24 -24
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-10-11 09:30+0000\n" "POT-Creation-Date: 2022-11-21 14:52+0000\n"
"PO-Revision-Date: 2021-09-15 11:22+0000\n" "PO-Revision-Date: 2021-09-15 11:22+0000\n"
"Last-Translator: Mohamed Tawfiq <mtawfiq@wafyapp.com>\n" "Last-Translator: Mohamed Tawfiq <mtawfiq@wafyapp.com>\n"
"Language-Team: Arabic <https://translate.pretix.eu/projects/pretix/pretix-js/" "Language-Team: Arabic <https://translate.pretix.eu/projects/pretix/pretix-js/"
@@ -132,18 +132,18 @@ msgstr ""
msgid "Mercado Pago" msgid "Mercado Pago"
msgstr "" msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:157 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:163
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:48 #: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:48
msgid "Continue" msgid "Continue"
msgstr "المتابعة" msgstr "المتابعة"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:215 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:221
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:152 #: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:152
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:183 #: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:183
msgid "Confirming your payment …" msgid "Confirming your payment …"
msgstr "جاري تأكيد الدفع الخاص بك …" msgstr "جاري تأكيد الدفع الخاص بك …"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:240 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:246
msgid "Payment method unavailable" msgid "Payment method unavailable"
msgstr "" msgstr ""
@@ -486,48 +486,48 @@ msgstr "الدقائق"
msgid "Check-in QR" msgid "Check-in QR"
msgstr "QR الدخول" msgstr "QR الدخول"
#: pretix/static/pretixcontrol/js/ui/editor.js:378 #: pretix/static/pretixcontrol/js/ui/editor.js:384
msgid "The PDF background file could not be loaded for the following reason:" msgid "The PDF background file could not be loaded for the following reason:"
msgstr "لا يمكن تحميل ملف PDF الخلفية للأسباب التالية:" msgstr "لا يمكن تحميل ملف PDF الخلفية للأسباب التالية:"
#: pretix/static/pretixcontrol/js/ui/editor.js:648 #: pretix/static/pretixcontrol/js/ui/editor.js:653
msgid "Group of objects" msgid "Group of objects"
msgstr "مجموعة من العناصر" msgstr "مجموعة من العناصر"
#: pretix/static/pretixcontrol/js/ui/editor.js:654 #: pretix/static/pretixcontrol/js/ui/editor.js:659
msgid "Text object" msgid "Text object"
msgstr "عنصر نص" msgstr "عنصر نص"
#: pretix/static/pretixcontrol/js/ui/editor.js:656 #: pretix/static/pretixcontrol/js/ui/editor.js:661
msgid "Barcode area" msgid "Barcode area"
msgstr "منطقة باركود" msgstr "منطقة باركود"
#: pretix/static/pretixcontrol/js/ui/editor.js:658 #: pretix/static/pretixcontrol/js/ui/editor.js:663
msgid "Image area" msgid "Image area"
msgstr "منطقة صورة" msgstr "منطقة صورة"
#: pretix/static/pretixcontrol/js/ui/editor.js:660 #: pretix/static/pretixcontrol/js/ui/editor.js:665
msgid "Powered by pretix" msgid "Powered by pretix"
msgstr "مدعوم من pretix" msgstr "مدعوم من pretix"
#: pretix/static/pretixcontrol/js/ui/editor.js:662 #: pretix/static/pretixcontrol/js/ui/editor.js:667
msgid "Object" msgid "Object"
msgstr "عنصر" msgstr "عنصر"
#: pretix/static/pretixcontrol/js/ui/editor.js:666 #: pretix/static/pretixcontrol/js/ui/editor.js:671
msgid "Ticket design" msgid "Ticket design"
msgstr "تصميم التذكرة" msgstr "تصميم التذكرة"
#: pretix/static/pretixcontrol/js/ui/editor.js:956 #: pretix/static/pretixcontrol/js/ui/editor.js:961
msgid "Saving failed." msgid "Saving failed."
msgstr "فشلت عملية الحفظ." msgstr "فشلت عملية الحفظ."
#: pretix/static/pretixcontrol/js/ui/editor.js:1006 #: pretix/static/pretixcontrol/js/ui/editor.js:1011
#: pretix/static/pretixcontrol/js/ui/editor.js:1045 #: pretix/static/pretixcontrol/js/ui/editor.js:1050
msgid "Error while uploading your PDF file, please try again." msgid "Error while uploading your PDF file, please try again."
msgstr "حصل خطأ أثناء رفع ملف PDF الخاص بك، يرجى المحاولة مرة أخرى." msgstr "حصل خطأ أثناء رفع ملف PDF الخاص بك، يرجى المحاولة مرة أخرى."
#: pretix/static/pretixcontrol/js/ui/editor.js:1030 #: pretix/static/pretixcontrol/js/ui/editor.js:1035
msgid "Do you really want to leave the editor without saving your changes?" msgid "Do you really want to leave the editor without saving your changes?"
msgstr "هل تريد أن تغادر المحرر دون حفظ التعديلات؟" msgstr "هل تريد أن تغادر المحرر دون حفظ التعديلات؟"
@@ -643,32 +643,32 @@ msgstr[3] "سيتم حجز العناصر لك في سلة التسوق لعدة
msgstr[4] "سيتم حجز العناصر لك في سلة التسوق لدقائق {num}." msgstr[4] "سيتم حجز العناصر لك في سلة التسوق لدقائق {num}."
msgstr[5] "سيتم حجز العناصر لك في سلة التسوق لمدة {num}." msgstr[5] "سيتم حجز العناصر لك في سلة التسوق لمدة {num}."
#: pretix/static/pretixpresale/js/ui/main.js:144 #: pretix/static/pretixpresale/js/ui/main.js:152
msgid "The organizer keeps %(currency)s %(amount)s" msgid "The organizer keeps %(currency)s %(amount)s"
msgstr "يحصل المنظم على %(currency) %(amount)" msgstr "يحصل المنظم على %(currency) %(amount)"
#: pretix/static/pretixpresale/js/ui/main.js:152 #: pretix/static/pretixpresale/js/ui/main.js:160
msgid "You get %(currency)s %(amount)s back" msgid "You get %(currency)s %(amount)s back"
msgstr "ستسترد %(currency)%(amount)" msgstr "ستسترد %(currency)%(amount)"
#: pretix/static/pretixpresale/js/ui/main.js:168 #: pretix/static/pretixpresale/js/ui/main.js:176
msgid "Please enter the amount the organizer can keep." msgid "Please enter the amount the organizer can keep."
msgstr "الرجاء إدخال المبلغ الذي يمكن للمنظم الاحتفاظ به." msgstr "الرجاء إدخال المبلغ الذي يمكن للمنظم الاحتفاظ به."
#: pretix/static/pretixpresale/js/ui/main.js:380 #: pretix/static/pretixpresale/js/ui/main.js:388
msgid "Please enter a quantity for one of the ticket types." msgid "Please enter a quantity for one of the ticket types."
msgstr "الرجاء إدخال عدد لأحد أنواع التذاكر." msgstr "الرجاء إدخال عدد لأحد أنواع التذاكر."
#: pretix/static/pretixpresale/js/ui/main.js:416 #: pretix/static/pretixpresale/js/ui/main.js:424
msgid "required" msgid "required"
msgstr "مطلوب" msgstr "مطلوب"
#: pretix/static/pretixpresale/js/ui/main.js:519 #: pretix/static/pretixpresale/js/ui/main.js:527
#: pretix/static/pretixpresale/js/ui/main.js:538 #: pretix/static/pretixpresale/js/ui/main.js:546
msgid "Time zone:" msgid "Time zone:"
msgstr "المنطقة الزمنية:" msgstr "المنطقة الزمنية:"
#: pretix/static/pretixpresale/js/ui/main.js:529 #: pretix/static/pretixpresale/js/ui/main.js:537
msgid "Your local time:" msgid "Your local time:"
msgstr "التوقيت المحلي:" msgstr "التوقيت المحلي:"
File diff suppressed because it is too large Load Diff
+24 -24
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-10-11 09:30+0000\n" "POT-Creation-Date: 2022-11-21 14:52+0000\n"
"PO-Revision-Date: 2020-12-19 07:00+0000\n" "PO-Revision-Date: 2020-12-19 07:00+0000\n"
"Last-Translator: albert <albert.serra.monner@gmail.com>\n" "Last-Translator: albert <albert.serra.monner@gmail.com>\n"
"Language-Team: Catalan <https://translate.pretix.eu/projects/pretix/pretix-" "Language-Team: Catalan <https://translate.pretix.eu/projects/pretix/pretix-"
@@ -129,18 +129,18 @@ msgstr ""
msgid "Mercado Pago" msgid "Mercado Pago"
msgstr "" msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:157 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:163
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:48 #: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:48
msgid "Continue" msgid "Continue"
msgstr "" msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:215 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:221
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:152 #: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:152
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:183 #: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:183
msgid "Confirming your payment …" msgid "Confirming your payment …"
msgstr "" msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:240 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:246
msgid "Payment method unavailable" msgid "Payment method unavailable"
msgstr "" msgstr ""
@@ -469,48 +469,48 @@ msgstr ""
msgid "Check-in QR" msgid "Check-in QR"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:378 #: pretix/static/pretixcontrol/js/ui/editor.js:384
msgid "The PDF background file could not be loaded for the following reason:" msgid "The PDF background file could not be loaded for the following reason:"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:648 #: pretix/static/pretixcontrol/js/ui/editor.js:653
msgid "Group of objects" msgid "Group of objects"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:654 #: pretix/static/pretixcontrol/js/ui/editor.js:659
msgid "Text object" msgid "Text object"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:656 #: pretix/static/pretixcontrol/js/ui/editor.js:661
msgid "Barcode area" msgid "Barcode area"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:658 #: pretix/static/pretixcontrol/js/ui/editor.js:663
msgid "Image area" msgid "Image area"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:660 #: pretix/static/pretixcontrol/js/ui/editor.js:665
msgid "Powered by pretix" msgid "Powered by pretix"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:662 #: pretix/static/pretixcontrol/js/ui/editor.js:667
msgid "Object" msgid "Object"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:666 #: pretix/static/pretixcontrol/js/ui/editor.js:671
msgid "Ticket design" msgid "Ticket design"
msgstr "Disseny del tiquet" msgstr "Disseny del tiquet"
#: pretix/static/pretixcontrol/js/ui/editor.js:956 #: pretix/static/pretixcontrol/js/ui/editor.js:961
msgid "Saving failed." msgid "Saving failed."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:1006 #: pretix/static/pretixcontrol/js/ui/editor.js:1011
#: pretix/static/pretixcontrol/js/ui/editor.js:1045 #: pretix/static/pretixcontrol/js/ui/editor.js:1050
msgid "Error while uploading your PDF file, please try again." msgid "Error while uploading your PDF file, please try again."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:1030 #: pretix/static/pretixcontrol/js/ui/editor.js:1035
msgid "Do you really want to leave the editor without saving your changes?" msgid "Do you really want to leave the editor without saving your changes?"
msgstr "" msgstr ""
@@ -616,34 +616,34 @@ msgid_plural "The items in your cart are reserved for you for {num} minutes."
msgstr[0] "El contingut de la cistella ja no el teniu reservat." msgstr[0] "El contingut de la cistella ja no el teniu reservat."
msgstr[1] "El contingut de la cistella ja no el teniu reservat." msgstr[1] "El contingut de la cistella ja no el teniu reservat."
#: pretix/static/pretixpresale/js/ui/main.js:144 #: pretix/static/pretixpresale/js/ui/main.js:152
msgid "The organizer keeps %(currency)s %(amount)s" msgid "The organizer keeps %(currency)s %(amount)s"
msgstr "" msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:152 #: pretix/static/pretixpresale/js/ui/main.js:160
msgid "You get %(currency)s %(amount)s back" msgid "You get %(currency)s %(amount)s back"
msgstr "" msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:168 #: pretix/static/pretixpresale/js/ui/main.js:176
msgid "Please enter the amount the organizer can keep." msgid "Please enter the amount the organizer can keep."
msgstr "" msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:380 #: pretix/static/pretixpresale/js/ui/main.js:388
msgid "Please enter a quantity for one of the ticket types." msgid "Please enter a quantity for one of the ticket types."
msgstr "" msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:416 #: pretix/static/pretixpresale/js/ui/main.js:424
#, fuzzy #, fuzzy
#| msgid "Cart expired" #| msgid "Cart expired"
msgid "required" msgid "required"
msgstr "Cistella expirada" msgstr "Cistella expirada"
#: pretix/static/pretixpresale/js/ui/main.js:519 #: pretix/static/pretixpresale/js/ui/main.js:527
#: pretix/static/pretixpresale/js/ui/main.js:538 #: pretix/static/pretixpresale/js/ui/main.js:546
msgid "Time zone:" msgid "Time zone:"
msgstr "" msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:529 #: pretix/static/pretixpresale/js/ui/main.js:537
msgid "Your local time:" msgid "Your local time:"
msgstr "" msgstr ""
File diff suppressed because it is too large Load Diff
+24 -24
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-10-11 09:30+0000\n" "POT-Creation-Date: 2022-11-21 14:52+0000\n"
"PO-Revision-Date: 2021-12-06 23:00+0000\n" "PO-Revision-Date: 2021-12-06 23:00+0000\n"
"Last-Translator: Ondřej Sokol <osokol@treesoft.cz>\n" "Last-Translator: Ondřej Sokol <osokol@treesoft.cz>\n"
"Language-Team: Czech <https://translate.pretix.eu/projects/pretix/pretix-js/" "Language-Team: Czech <https://translate.pretix.eu/projects/pretix/pretix-js/"
@@ -131,18 +131,18 @@ msgstr ""
msgid "Mercado Pago" msgid "Mercado Pago"
msgstr "" msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:157 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:163
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:48 #: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:48
msgid "Continue" msgid "Continue"
msgstr "Pokračovat" msgstr "Pokračovat"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:215 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:221
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:152 #: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:152
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:183 #: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:183
msgid "Confirming your payment …" msgid "Confirming your payment …"
msgstr "Potvrzuji vaši platbu …" msgstr "Potvrzuji vaši platbu …"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:240 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:246
msgid "Payment method unavailable" msgid "Payment method unavailable"
msgstr "" msgstr ""
@@ -483,48 +483,48 @@ msgstr "minuty"
msgid "Check-in QR" msgid "Check-in QR"
msgstr "Check-in QR kód" msgstr "Check-in QR kód"
#: pretix/static/pretixcontrol/js/ui/editor.js:378 #: pretix/static/pretixcontrol/js/ui/editor.js:384
msgid "The PDF background file could not be loaded for the following reason:" msgid "The PDF background file could not be loaded for the following reason:"
msgstr "Pozadí PDF nemohl být načten:" msgstr "Pozadí PDF nemohl být načten:"
#: pretix/static/pretixcontrol/js/ui/editor.js:648 #: pretix/static/pretixcontrol/js/ui/editor.js:653
msgid "Group of objects" msgid "Group of objects"
msgstr "Skupina objektů" msgstr "Skupina objektů"
#: pretix/static/pretixcontrol/js/ui/editor.js:654 #: pretix/static/pretixcontrol/js/ui/editor.js:659
msgid "Text object" msgid "Text object"
msgstr "Textový objekt" msgstr "Textový objekt"
#: pretix/static/pretixcontrol/js/ui/editor.js:656 #: pretix/static/pretixcontrol/js/ui/editor.js:661
msgid "Barcode area" msgid "Barcode area"
msgstr "Oblast s QR kódem" msgstr "Oblast s QR kódem"
#: pretix/static/pretixcontrol/js/ui/editor.js:658 #: pretix/static/pretixcontrol/js/ui/editor.js:663
msgid "Image area" msgid "Image area"
msgstr "Oblast obrazu" msgstr "Oblast obrazu"
#: pretix/static/pretixcontrol/js/ui/editor.js:660 #: pretix/static/pretixcontrol/js/ui/editor.js:665
msgid "Powered by pretix" msgid "Powered by pretix"
msgstr "Poháněno společností pretix" msgstr "Poháněno společností pretix"
#: pretix/static/pretixcontrol/js/ui/editor.js:662 #: pretix/static/pretixcontrol/js/ui/editor.js:667
msgid "Object" msgid "Object"
msgstr "Objekt" msgstr "Objekt"
#: pretix/static/pretixcontrol/js/ui/editor.js:666 #: pretix/static/pretixcontrol/js/ui/editor.js:671
msgid "Ticket design" msgid "Ticket design"
msgstr "Design vstupenky" msgstr "Design vstupenky"
#: pretix/static/pretixcontrol/js/ui/editor.js:956 #: pretix/static/pretixcontrol/js/ui/editor.js:961
msgid "Saving failed." msgid "Saving failed."
msgstr "Uložení se nepodařilo." msgstr "Uložení se nepodařilo."
#: pretix/static/pretixcontrol/js/ui/editor.js:1006 #: pretix/static/pretixcontrol/js/ui/editor.js:1011
#: pretix/static/pretixcontrol/js/ui/editor.js:1045 #: pretix/static/pretixcontrol/js/ui/editor.js:1050
msgid "Error while uploading your PDF file, please try again." msgid "Error while uploading your PDF file, please try again."
msgstr "Při nahrávání souboru PDF došlo k problému, zkuste to prosím znovu." msgstr "Při nahrávání souboru PDF došlo k problému, zkuste to prosím znovu."
#: pretix/static/pretixcontrol/js/ui/editor.js:1030 #: pretix/static/pretixcontrol/js/ui/editor.js:1035
msgid "Do you really want to leave the editor without saving your changes?" msgid "Do you really want to leave the editor without saving your changes?"
msgstr "Opravdu chcete opustit editor bez uložení změn?" msgstr "Opravdu chcete opustit editor bez uložení změn?"
@@ -636,32 +636,32 @@ msgstr[1] ""
msgstr[2] "" msgstr[2] ""
"Produkty v nákupním košíku jsou pro vás rezervovány na dalších {num} minut." "Produkty v nákupním košíku jsou pro vás rezervovány na dalších {num} minut."
#: pretix/static/pretixpresale/js/ui/main.js:144 #: pretix/static/pretixpresale/js/ui/main.js:152
msgid "The organizer keeps %(currency)s %(amount)s" msgid "The organizer keeps %(currency)s %(amount)s"
msgstr "Organizátor si ponechává %(currency)s %(amount)s" msgstr "Organizátor si ponechává %(currency)s %(amount)s"
#: pretix/static/pretixpresale/js/ui/main.js:152 #: pretix/static/pretixpresale/js/ui/main.js:160
msgid "You get %(currency)s %(amount)s back" msgid "You get %(currency)s %(amount)s back"
msgstr "Dostanete %(currency)s %(amount)s zpět" msgstr "Dostanete %(currency)s %(amount)s zpět"
#: pretix/static/pretixpresale/js/ui/main.js:168 #: pretix/static/pretixpresale/js/ui/main.js:176
msgid "Please enter the amount the organizer can keep." msgid "Please enter the amount the organizer can keep."
msgstr "Zadejte částku, kterou si organizátor může ponechat." msgstr "Zadejte částku, kterou si organizátor může ponechat."
#: pretix/static/pretixpresale/js/ui/main.js:380 #: pretix/static/pretixpresale/js/ui/main.js:388
msgid "Please enter a quantity for one of the ticket types." msgid "Please enter a quantity for one of the ticket types."
msgstr "Zadejte prosím množství pro jeden z typů vstupenek." msgstr "Zadejte prosím množství pro jeden z typů vstupenek."
#: pretix/static/pretixpresale/js/ui/main.js:416 #: pretix/static/pretixpresale/js/ui/main.js:424
msgid "required" msgid "required"
msgstr "povinný" msgstr "povinný"
#: pretix/static/pretixpresale/js/ui/main.js:519 #: pretix/static/pretixpresale/js/ui/main.js:527
#: pretix/static/pretixpresale/js/ui/main.js:538 #: pretix/static/pretixpresale/js/ui/main.js:546
msgid "Time zone:" msgid "Time zone:"
msgstr "Časové pásmo:" msgstr "Časové pásmo:"
#: pretix/static/pretixpresale/js/ui/main.js:529 #: pretix/static/pretixpresale/js/ui/main.js:537
msgid "Your local time:" msgid "Your local time:"
msgstr "Místní čas:" msgstr "Místní čas:"
File diff suppressed because it is too large Load Diff
+24 -24
View File
@@ -6,7 +6,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-10-11 09:30+0000\n" "POT-Creation-Date: 2022-11-21 14:52+0000\n"
"PO-Revision-Date: 2022-04-01 13:36+0000\n" "PO-Revision-Date: 2022-04-01 13:36+0000\n"
"Last-Translator: Anna-itk <abc@aarhus.dk>\n" "Last-Translator: Anna-itk <abc@aarhus.dk>\n"
"Language-Team: Danish <https://translate.pretix.eu/projects/pretix/pretix-js/" "Language-Team: Danish <https://translate.pretix.eu/projects/pretix/pretix-js/"
@@ -130,7 +130,7 @@ msgstr ""
msgid "Mercado Pago" msgid "Mercado Pago"
msgstr "" msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:157 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:163
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:48 #: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:48
#, fuzzy #, fuzzy
#| msgctxt "widget" #| msgctxt "widget"
@@ -138,13 +138,13 @@ msgstr ""
msgid "Continue" msgid "Continue"
msgstr "Fortsæt" msgstr "Fortsæt"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:215 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:221
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:152 #: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:152
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:183 #: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:183
msgid "Confirming your payment …" msgid "Confirming your payment …"
msgstr "Bekræfter din betaling …" msgstr "Bekræfter din betaling …"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:240 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:246
msgid "Payment method unavailable" msgid "Payment method unavailable"
msgstr "" msgstr ""
@@ -511,50 +511,50 @@ msgstr ""
msgid "Check-in QR" msgid "Check-in QR"
msgstr "Check-in QR" msgstr "Check-in QR"
#: pretix/static/pretixcontrol/js/ui/editor.js:378 #: pretix/static/pretixcontrol/js/ui/editor.js:384
msgid "The PDF background file could not be loaded for the following reason:" msgid "The PDF background file could not be loaded for the following reason:"
msgstr "Baggrunds-pdf'en kunne ikke hentes af følgende grund:" msgstr "Baggrunds-pdf'en kunne ikke hentes af følgende grund:"
#: pretix/static/pretixcontrol/js/ui/editor.js:648 #: pretix/static/pretixcontrol/js/ui/editor.js:653
msgid "Group of objects" msgid "Group of objects"
msgstr "Gruppe af objekter" msgstr "Gruppe af objekter"
#: pretix/static/pretixcontrol/js/ui/editor.js:654 #: pretix/static/pretixcontrol/js/ui/editor.js:659
msgid "Text object" msgid "Text object"
msgstr "Tekstobjekt" msgstr "Tekstobjekt"
#: pretix/static/pretixcontrol/js/ui/editor.js:656 #: pretix/static/pretixcontrol/js/ui/editor.js:661
msgid "Barcode area" msgid "Barcode area"
msgstr "QR-kode-område" msgstr "QR-kode-område"
#: pretix/static/pretixcontrol/js/ui/editor.js:658 #: pretix/static/pretixcontrol/js/ui/editor.js:663
#, fuzzy #, fuzzy
#| msgid "Barcode area" #| msgid "Barcode area"
msgid "Image area" msgid "Image area"
msgstr "QR-kode-område" msgstr "QR-kode-område"
#: pretix/static/pretixcontrol/js/ui/editor.js:660 #: pretix/static/pretixcontrol/js/ui/editor.js:665
msgid "Powered by pretix" msgid "Powered by pretix"
msgstr "Drevet af pretix" msgstr "Drevet af pretix"
#: pretix/static/pretixcontrol/js/ui/editor.js:662 #: pretix/static/pretixcontrol/js/ui/editor.js:667
msgid "Object" msgid "Object"
msgstr "Objekt" msgstr "Objekt"
#: pretix/static/pretixcontrol/js/ui/editor.js:666 #: pretix/static/pretixcontrol/js/ui/editor.js:671
msgid "Ticket design" msgid "Ticket design"
msgstr "Billetdesign" msgstr "Billetdesign"
#: pretix/static/pretixcontrol/js/ui/editor.js:956 #: pretix/static/pretixcontrol/js/ui/editor.js:961
msgid "Saving failed." msgid "Saving failed."
msgstr "Gem fejlede." msgstr "Gem fejlede."
#: pretix/static/pretixcontrol/js/ui/editor.js:1006 #: pretix/static/pretixcontrol/js/ui/editor.js:1011
#: pretix/static/pretixcontrol/js/ui/editor.js:1045 #: pretix/static/pretixcontrol/js/ui/editor.js:1050
msgid "Error while uploading your PDF file, please try again." msgid "Error while uploading your PDF file, please try again."
msgstr "Fejl under upload af pdf. Prøv venligt igen." msgstr "Fejl under upload af pdf. Prøv venligt igen."
#: pretix/static/pretixcontrol/js/ui/editor.js:1030 #: pretix/static/pretixcontrol/js/ui/editor.js:1035
msgid "Do you really want to leave the editor without saving your changes?" msgid "Do you really want to leave the editor without saving your changes?"
msgstr "" msgstr ""
"Er du sikker på at du vil forlade editoren uden at gemme dine ændringer?" "Er du sikker på at du vil forlade editoren uden at gemme dine ændringer?"
@@ -665,40 +665,40 @@ msgid_plural "The items in your cart are reserved for you for {num} minutes."
msgstr[0] "Varerne i din kurv er reserveret for dig i et minut." msgstr[0] "Varerne i din kurv er reserveret for dig i et minut."
msgstr[1] "Varerne i din kurv er reserveret for dig i {num} minutter." msgstr[1] "Varerne i din kurv er reserveret for dig i {num} minutter."
#: pretix/static/pretixpresale/js/ui/main.js:144 #: pretix/static/pretixpresale/js/ui/main.js:152
#, fuzzy #, fuzzy
#| msgctxt "widget" #| msgctxt "widget"
#| msgid "from %(currency)s %(price)s" #| msgid "from %(currency)s %(price)s"
msgid "The organizer keeps %(currency)s %(amount)s" msgid "The organizer keeps %(currency)s %(amount)s"
msgstr "fra %(currency)s %(price)s" msgstr "fra %(currency)s %(price)s"
#: pretix/static/pretixpresale/js/ui/main.js:152 #: pretix/static/pretixpresale/js/ui/main.js:160
#, fuzzy #, fuzzy
#| msgctxt "widget" #| msgctxt "widget"
#| msgid "from %(currency)s %(price)s" #| msgid "from %(currency)s %(price)s"
msgid "You get %(currency)s %(amount)s back" msgid "You get %(currency)s %(amount)s back"
msgstr "fra %(currency)s %(price)s" msgstr "fra %(currency)s %(price)s"
#: pretix/static/pretixpresale/js/ui/main.js:168 #: pretix/static/pretixpresale/js/ui/main.js:176
msgid "Please enter the amount the organizer can keep." msgid "Please enter the amount the organizer can keep."
msgstr "" msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:380 #: pretix/static/pretixpresale/js/ui/main.js:388
msgid "Please enter a quantity for one of the ticket types." msgid "Please enter a quantity for one of the ticket types."
msgstr "" msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:416 #: pretix/static/pretixpresale/js/ui/main.js:424
#, fuzzy #, fuzzy
#| msgid "Cart expired" #| msgid "Cart expired"
msgid "required" msgid "required"
msgstr "Kurv udløbet" msgstr "Kurv udløbet"
#: pretix/static/pretixpresale/js/ui/main.js:519 #: pretix/static/pretixpresale/js/ui/main.js:527
#: pretix/static/pretixpresale/js/ui/main.js:538 #: pretix/static/pretixpresale/js/ui/main.js:546
msgid "Time zone:" msgid "Time zone:"
msgstr "Tidszone:" msgstr "Tidszone:"
#: pretix/static/pretixpresale/js/ui/main.js:529 #: pretix/static/pretixpresale/js/ui/main.js:537
msgid "Your local time:" msgid "Your local time:"
msgstr "Din lokaltid:" msgstr "Din lokaltid:"
File diff suppressed because it is too large Load Diff
+24 -24
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-10-11 09:30+0000\n" "POT-Creation-Date: 2022-11-21 14:52+0000\n"
"PO-Revision-Date: 2022-07-26 08:58+0000\n" "PO-Revision-Date: 2022-07-26 08:58+0000\n"
"Last-Translator: Raphael Michel <michel@rami.io>\n" "Last-Translator: Raphael Michel <michel@rami.io>\n"
"Language-Team: German <https://translate.pretix.eu/projects/pretix/pretix-js/" "Language-Team: German <https://translate.pretix.eu/projects/pretix/pretix-js/"
@@ -129,18 +129,18 @@ msgstr "WeChat Pay"
msgid "Mercado Pago" msgid "Mercado Pago"
msgstr "Mercado Pago" msgstr "Mercado Pago"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:157 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:163
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:48 #: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:48
msgid "Continue" msgid "Continue"
msgstr "Fortfahren" msgstr "Fortfahren"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:215 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:221
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:152 #: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:152
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:183 #: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:183
msgid "Confirming your payment …" msgid "Confirming your payment …"
msgstr "Zahlung wird bestätigt …" msgstr "Zahlung wird bestätigt …"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:240 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:246
msgid "Payment method unavailable" msgid "Payment method unavailable"
msgstr "Zahlungsmethode nicht verfügbar" msgstr "Zahlungsmethode nicht verfügbar"
@@ -484,49 +484,49 @@ msgstr "Minuten"
msgid "Check-in QR" msgid "Check-in QR"
msgstr "Check-in-QR-Code" msgstr "Check-in-QR-Code"
#: pretix/static/pretixcontrol/js/ui/editor.js:378 #: pretix/static/pretixcontrol/js/ui/editor.js:384
msgid "The PDF background file could not be loaded for the following reason:" msgid "The PDF background file could not be loaded for the following reason:"
msgstr "Die Hintergrund-PDF-Datei konnte nicht geladen werden:" msgstr "Die Hintergrund-PDF-Datei konnte nicht geladen werden:"
#: pretix/static/pretixcontrol/js/ui/editor.js:648 #: pretix/static/pretixcontrol/js/ui/editor.js:653
msgid "Group of objects" msgid "Group of objects"
msgstr "Gruppe von Objekten" msgstr "Gruppe von Objekten"
#: pretix/static/pretixcontrol/js/ui/editor.js:654 #: pretix/static/pretixcontrol/js/ui/editor.js:659
msgid "Text object" msgid "Text object"
msgstr "Text-Objekt" msgstr "Text-Objekt"
#: pretix/static/pretixcontrol/js/ui/editor.js:656 #: pretix/static/pretixcontrol/js/ui/editor.js:661
msgid "Barcode area" msgid "Barcode area"
msgstr "QR-Code-Bereich" msgstr "QR-Code-Bereich"
#: pretix/static/pretixcontrol/js/ui/editor.js:658 #: pretix/static/pretixcontrol/js/ui/editor.js:663
msgid "Image area" msgid "Image area"
msgstr "Bildbereich" msgstr "Bildbereich"
#: pretix/static/pretixcontrol/js/ui/editor.js:660 #: pretix/static/pretixcontrol/js/ui/editor.js:665
msgid "Powered by pretix" msgid "Powered by pretix"
msgstr "Event-Ticketshop von pretix" msgstr "Event-Ticketshop von pretix"
#: pretix/static/pretixcontrol/js/ui/editor.js:662 #: pretix/static/pretixcontrol/js/ui/editor.js:667
msgid "Object" msgid "Object"
msgstr "Objekt" msgstr "Objekt"
#: pretix/static/pretixcontrol/js/ui/editor.js:666 #: pretix/static/pretixcontrol/js/ui/editor.js:671
msgid "Ticket design" msgid "Ticket design"
msgstr "Ticket-Design" msgstr "Ticket-Design"
#: pretix/static/pretixcontrol/js/ui/editor.js:956 #: pretix/static/pretixcontrol/js/ui/editor.js:961
msgid "Saving failed." msgid "Saving failed."
msgstr "Speichern fehlgeschlagen." msgstr "Speichern fehlgeschlagen."
#: pretix/static/pretixcontrol/js/ui/editor.js:1006 #: pretix/static/pretixcontrol/js/ui/editor.js:1011
#: pretix/static/pretixcontrol/js/ui/editor.js:1045 #: pretix/static/pretixcontrol/js/ui/editor.js:1050
msgid "Error while uploading your PDF file, please try again." msgid "Error while uploading your PDF file, please try again."
msgstr "" msgstr ""
"Es gab ein Problem beim Hochladen der PDF-Datei, bitte erneut versuchen." "Es gab ein Problem beim Hochladen der PDF-Datei, bitte erneut versuchen."
#: pretix/static/pretixcontrol/js/ui/editor.js:1030 #: pretix/static/pretixcontrol/js/ui/editor.js:1035
msgid "Do you really want to leave the editor without saving your changes?" msgid "Do you really want to leave the editor without saving your changes?"
msgstr "" msgstr ""
"Möchten Sie den Editor wirklich schließen ohne Ihre Änderungen zu speichern?" "Möchten Sie den Editor wirklich schließen ohne Ihre Änderungen zu speichern?"
@@ -638,32 +638,32 @@ msgstr[0] ""
msgstr[1] "" msgstr[1] ""
"Die Produkte in Ihrem Warenkorb sind noch {num} Minuten für Sie reserviert." "Die Produkte in Ihrem Warenkorb sind noch {num} Minuten für Sie reserviert."
#: pretix/static/pretixpresale/js/ui/main.js:144 #: pretix/static/pretixpresale/js/ui/main.js:152
msgid "The organizer keeps %(currency)s %(amount)s" msgid "The organizer keeps %(currency)s %(amount)s"
msgstr "Der Veranstalter behält %(currency)s %(amount)s ein" msgstr "Der Veranstalter behält %(currency)s %(amount)s ein"
#: pretix/static/pretixpresale/js/ui/main.js:152 #: pretix/static/pretixpresale/js/ui/main.js:160
msgid "You get %(currency)s %(amount)s back" msgid "You get %(currency)s %(amount)s back"
msgstr "Sie erhalten %(currency)s %(amount)s zurück" msgstr "Sie erhalten %(currency)s %(amount)s zurück"
#: pretix/static/pretixpresale/js/ui/main.js:168 #: pretix/static/pretixpresale/js/ui/main.js:176
msgid "Please enter the amount the organizer can keep." msgid "Please enter the amount the organizer can keep."
msgstr "Bitte geben Sie den Betrag ein, den der Veranstalter einbehalten darf." msgstr "Bitte geben Sie den Betrag ein, den der Veranstalter einbehalten darf."
#: pretix/static/pretixpresale/js/ui/main.js:380 #: pretix/static/pretixpresale/js/ui/main.js:388
msgid "Please enter a quantity for one of the ticket types." msgid "Please enter a quantity for one of the ticket types."
msgstr "Bitte tragen Sie eine Menge für eines der Produkte ein." msgstr "Bitte tragen Sie eine Menge für eines der Produkte ein."
#: pretix/static/pretixpresale/js/ui/main.js:416 #: pretix/static/pretixpresale/js/ui/main.js:424
msgid "required" msgid "required"
msgstr "verpflichtend" msgstr "verpflichtend"
#: pretix/static/pretixpresale/js/ui/main.js:519 #: pretix/static/pretixpresale/js/ui/main.js:527
#: pretix/static/pretixpresale/js/ui/main.js:538 #: pretix/static/pretixpresale/js/ui/main.js:546
msgid "Time zone:" msgid "Time zone:"
msgstr "Zeitzone:" msgstr "Zeitzone:"
#: pretix/static/pretixpresale/js/ui/main.js:529 #: pretix/static/pretixpresale/js/ui/main.js:537
msgid "Your local time:" msgid "Your local time:"
msgstr "Deine lokale Zeit:" msgstr "Deine lokale Zeit:"
File diff suppressed because it is too large Load Diff
@@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-10-11 09:30+0000\n" "POT-Creation-Date: 2022-11-21 14:52+0000\n"
"PO-Revision-Date: 2022-07-26 08:58+0000\n" "PO-Revision-Date: 2022-07-26 08:58+0000\n"
"Last-Translator: Raphael Michel <michel@rami.io>\n" "Last-Translator: Raphael Michel <michel@rami.io>\n"
"Language-Team: German (informal) <https://translate.pretix.eu/projects/" "Language-Team: German (informal) <https://translate.pretix.eu/projects/"
@@ -129,18 +129,18 @@ msgstr "WeChat Pay"
msgid "Mercado Pago" msgid "Mercado Pago"
msgstr "Mercado Pago" msgstr "Mercado Pago"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:157 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:163
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:48 #: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:48
msgid "Continue" msgid "Continue"
msgstr "Fortfahren" msgstr "Fortfahren"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:215 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:221
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:152 #: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:152
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:183 #: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:183
msgid "Confirming your payment …" msgid "Confirming your payment …"
msgstr "Zahlung wird bestätigt …" msgstr "Zahlung wird bestätigt …"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:240 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:246
msgid "Payment method unavailable" msgid "Payment method unavailable"
msgstr "Zahlungsmethode nicht verfügbar" msgstr "Zahlungsmethode nicht verfügbar"
@@ -483,49 +483,49 @@ msgstr "Minuten"
msgid "Check-in QR" msgid "Check-in QR"
msgstr "Check-in-QR-Code" msgstr "Check-in-QR-Code"
#: pretix/static/pretixcontrol/js/ui/editor.js:378 #: pretix/static/pretixcontrol/js/ui/editor.js:384
msgid "The PDF background file could not be loaded for the following reason:" msgid "The PDF background file could not be loaded for the following reason:"
msgstr "Die Hintergrund-PDF-Datei konnte nicht geladen werden:" msgstr "Die Hintergrund-PDF-Datei konnte nicht geladen werden:"
#: pretix/static/pretixcontrol/js/ui/editor.js:648 #: pretix/static/pretixcontrol/js/ui/editor.js:653
msgid "Group of objects" msgid "Group of objects"
msgstr "Gruppe von Objekten" msgstr "Gruppe von Objekten"
#: pretix/static/pretixcontrol/js/ui/editor.js:654 #: pretix/static/pretixcontrol/js/ui/editor.js:659
msgid "Text object" msgid "Text object"
msgstr "Text-Objekt" msgstr "Text-Objekt"
#: pretix/static/pretixcontrol/js/ui/editor.js:656 #: pretix/static/pretixcontrol/js/ui/editor.js:661
msgid "Barcode area" msgid "Barcode area"
msgstr "QR-Code-Bereich" msgstr "QR-Code-Bereich"
#: pretix/static/pretixcontrol/js/ui/editor.js:658 #: pretix/static/pretixcontrol/js/ui/editor.js:663
msgid "Image area" msgid "Image area"
msgstr "Bildbereich" msgstr "Bildbereich"
#: pretix/static/pretixcontrol/js/ui/editor.js:660 #: pretix/static/pretixcontrol/js/ui/editor.js:665
msgid "Powered by pretix" msgid "Powered by pretix"
msgstr "Event-Ticketshop von pretix" msgstr "Event-Ticketshop von pretix"
#: pretix/static/pretixcontrol/js/ui/editor.js:662 #: pretix/static/pretixcontrol/js/ui/editor.js:667
msgid "Object" msgid "Object"
msgstr "Objekt" msgstr "Objekt"
#: pretix/static/pretixcontrol/js/ui/editor.js:666 #: pretix/static/pretixcontrol/js/ui/editor.js:671
msgid "Ticket design" msgid "Ticket design"
msgstr "Ticket-Design" msgstr "Ticket-Design"
#: pretix/static/pretixcontrol/js/ui/editor.js:956 #: pretix/static/pretixcontrol/js/ui/editor.js:961
msgid "Saving failed." msgid "Saving failed."
msgstr "Speichern fehlgeschlagen." msgstr "Speichern fehlgeschlagen."
#: pretix/static/pretixcontrol/js/ui/editor.js:1006 #: pretix/static/pretixcontrol/js/ui/editor.js:1011
#: pretix/static/pretixcontrol/js/ui/editor.js:1045 #: pretix/static/pretixcontrol/js/ui/editor.js:1050
msgid "Error while uploading your PDF file, please try again." msgid "Error while uploading your PDF file, please try again."
msgstr "" msgstr ""
"Es gab ein Problem beim Hochladen der PDF-Datei, bitte erneut versuchen." "Es gab ein Problem beim Hochladen der PDF-Datei, bitte erneut versuchen."
#: pretix/static/pretixcontrol/js/ui/editor.js:1030 #: pretix/static/pretixcontrol/js/ui/editor.js:1035
msgid "Do you really want to leave the editor without saving your changes?" msgid "Do you really want to leave the editor without saving your changes?"
msgstr "" msgstr ""
"Möchtest du den Editor wirklich schließen ohne Ihre Änderungen zu speichern?" "Möchtest du den Editor wirklich schließen ohne Ihre Änderungen zu speichern?"
@@ -637,32 +637,32 @@ msgstr[0] ""
msgstr[1] "" msgstr[1] ""
"Die Produkte in deinem Warenkorb sind noch {num} Minuten für dich reserviert." "Die Produkte in deinem Warenkorb sind noch {num} Minuten für dich reserviert."
#: pretix/static/pretixpresale/js/ui/main.js:144 #: pretix/static/pretixpresale/js/ui/main.js:152
msgid "The organizer keeps %(currency)s %(amount)s" msgid "The organizer keeps %(currency)s %(amount)s"
msgstr "Der Veranstalter behält %(currency)s %(amount)s ein" msgstr "Der Veranstalter behält %(currency)s %(amount)s ein"
#: pretix/static/pretixpresale/js/ui/main.js:152 #: pretix/static/pretixpresale/js/ui/main.js:160
msgid "You get %(currency)s %(amount)s back" msgid "You get %(currency)s %(amount)s back"
msgstr "Du erhältst %(currency)s %(amount)s zurück" msgstr "Du erhältst %(currency)s %(amount)s zurück"
#: pretix/static/pretixpresale/js/ui/main.js:168 #: pretix/static/pretixpresale/js/ui/main.js:176
msgid "Please enter the amount the organizer can keep." msgid "Please enter the amount the organizer can keep."
msgstr "Bitte gib den Betrag ein, den der Veranstalter einbehalten darf." msgstr "Bitte gib den Betrag ein, den der Veranstalter einbehalten darf."
#: pretix/static/pretixpresale/js/ui/main.js:380 #: pretix/static/pretixpresale/js/ui/main.js:388
msgid "Please enter a quantity for one of the ticket types." msgid "Please enter a quantity for one of the ticket types."
msgstr "Bitte trage eine Menge für eines der Produkte ein." msgstr "Bitte trage eine Menge für eines der Produkte ein."
#: pretix/static/pretixpresale/js/ui/main.js:416 #: pretix/static/pretixpresale/js/ui/main.js:424
msgid "required" msgid "required"
msgstr "verpflichtend" msgstr "verpflichtend"
#: pretix/static/pretixpresale/js/ui/main.js:519 #: pretix/static/pretixpresale/js/ui/main.js:527
#: pretix/static/pretixpresale/js/ui/main.js:538 #: pretix/static/pretixpresale/js/ui/main.js:546
msgid "Time zone:" msgid "Time zone:"
msgstr "Zeitzone:" msgstr "Zeitzone:"
#: pretix/static/pretixpresale/js/ui/main.js:529 #: pretix/static/pretixpresale/js/ui/main.js:537
msgid "Your local time:" msgid "Your local time:"
msgstr "Deine lokale Zeit:" msgstr "Deine lokale Zeit:"
+2201 -2018
View File
File diff suppressed because it is too large Load Diff
+24 -24
View File
@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-10-11 09:30+0000\n" "POT-Creation-Date: 2022-11-21 14:52+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -128,18 +128,18 @@ msgstr ""
msgid "Mercado Pago" msgid "Mercado Pago"
msgstr "" msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:157 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:163
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:48 #: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:48
msgid "Continue" msgid "Continue"
msgstr "" msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:215 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:221
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:152 #: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:152
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:183 #: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:183
msgid "Confirming your payment …" msgid "Confirming your payment …"
msgstr "" msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:240 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:246
msgid "Payment method unavailable" msgid "Payment method unavailable"
msgstr "" msgstr ""
@@ -468,48 +468,48 @@ msgstr ""
msgid "Check-in QR" msgid "Check-in QR"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:378 #: pretix/static/pretixcontrol/js/ui/editor.js:384
msgid "The PDF background file could not be loaded for the following reason:" msgid "The PDF background file could not be loaded for the following reason:"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:648 #: pretix/static/pretixcontrol/js/ui/editor.js:653
msgid "Group of objects" msgid "Group of objects"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:654 #: pretix/static/pretixcontrol/js/ui/editor.js:659
msgid "Text object" msgid "Text object"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:656 #: pretix/static/pretixcontrol/js/ui/editor.js:661
msgid "Barcode area" msgid "Barcode area"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:658 #: pretix/static/pretixcontrol/js/ui/editor.js:663
msgid "Image area" msgid "Image area"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:660 #: pretix/static/pretixcontrol/js/ui/editor.js:665
msgid "Powered by pretix" msgid "Powered by pretix"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:662 #: pretix/static/pretixcontrol/js/ui/editor.js:667
msgid "Object" msgid "Object"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:666 #: pretix/static/pretixcontrol/js/ui/editor.js:671
msgid "Ticket design" msgid "Ticket design"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:956 #: pretix/static/pretixcontrol/js/ui/editor.js:961
msgid "Saving failed." msgid "Saving failed."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:1006 #: pretix/static/pretixcontrol/js/ui/editor.js:1011
#: pretix/static/pretixcontrol/js/ui/editor.js:1045 #: pretix/static/pretixcontrol/js/ui/editor.js:1050
msgid "Error while uploading your PDF file, please try again." msgid "Error while uploading your PDF file, please try again."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:1030 #: pretix/static/pretixcontrol/js/ui/editor.js:1035
msgid "Do you really want to leave the editor without saving your changes?" msgid "Do you really want to leave the editor without saving your changes?"
msgstr "" msgstr ""
@@ -611,32 +611,32 @@ msgid_plural "The items in your cart are reserved for you for {num} minutes."
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
#: pretix/static/pretixpresale/js/ui/main.js:144 #: pretix/static/pretixpresale/js/ui/main.js:152
msgid "The organizer keeps %(currency)s %(amount)s" msgid "The organizer keeps %(currency)s %(amount)s"
msgstr "" msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:152 #: pretix/static/pretixpresale/js/ui/main.js:160
msgid "You get %(currency)s %(amount)s back" msgid "You get %(currency)s %(amount)s back"
msgstr "" msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:168 #: pretix/static/pretixpresale/js/ui/main.js:176
msgid "Please enter the amount the organizer can keep." msgid "Please enter the amount the organizer can keep."
msgstr "" msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:380 #: pretix/static/pretixpresale/js/ui/main.js:388
msgid "Please enter a quantity for one of the ticket types." msgid "Please enter a quantity for one of the ticket types."
msgstr "" msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:416 #: pretix/static/pretixpresale/js/ui/main.js:424
msgid "required" msgid "required"
msgstr "" msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:519 #: pretix/static/pretixpresale/js/ui/main.js:527
#: pretix/static/pretixpresale/js/ui/main.js:538 #: pretix/static/pretixpresale/js/ui/main.js:546
msgid "Time zone:" msgid "Time zone:"
msgstr "" msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:529 #: pretix/static/pretixpresale/js/ui/main.js:537
msgid "Your local time:" msgid "Your local time:"
msgstr "" msgstr ""
File diff suppressed because it is too large Load Diff
+24 -24
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-10-11 09:30+0000\n" "POT-Creation-Date: 2022-11-21 14:52+0000\n"
"PO-Revision-Date: 2019-10-03 19:00+0000\n" "PO-Revision-Date: 2019-10-03 19:00+0000\n"
"Last-Translator: Chris Spy <chrispiropoulou@hotmail.com>\n" "Last-Translator: Chris Spy <chrispiropoulou@hotmail.com>\n"
"Language-Team: Greek <https://translate.pretix.eu/projects/pretix/pretix-js/" "Language-Team: Greek <https://translate.pretix.eu/projects/pretix/pretix-js/"
@@ -131,7 +131,7 @@ msgstr ""
msgid "Mercado Pago" msgid "Mercado Pago"
msgstr "" msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:157 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:163
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:48 #: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:48
#, fuzzy #, fuzzy
#| msgctxt "widget" #| msgctxt "widget"
@@ -139,13 +139,13 @@ msgstr ""
msgid "Continue" msgid "Continue"
msgstr "Συνέχεια" msgstr "Συνέχεια"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:215 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:221
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:152 #: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:152
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:183 #: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:183
msgid "Confirming your payment …" msgid "Confirming your payment …"
msgstr "" msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:240 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:246
msgid "Payment method unavailable" msgid "Payment method unavailable"
msgstr "" msgstr ""
@@ -518,51 +518,51 @@ msgstr ""
msgid "Check-in QR" msgid "Check-in QR"
msgstr "Έλεγχος QR" msgstr "Έλεγχος QR"
#: pretix/static/pretixcontrol/js/ui/editor.js:378 #: pretix/static/pretixcontrol/js/ui/editor.js:384
msgid "The PDF background file could not be loaded for the following reason:" msgid "The PDF background file could not be loaded for the following reason:"
msgstr "" msgstr ""
"Το αρχείο φόντου PDF δεν ήταν δυνατό να φορτωθεί για τον ακόλουθο λόγο:" "Το αρχείο φόντου PDF δεν ήταν δυνατό να φορτωθεί για τον ακόλουθο λόγο:"
#: pretix/static/pretixcontrol/js/ui/editor.js:648 #: pretix/static/pretixcontrol/js/ui/editor.js:653
msgid "Group of objects" msgid "Group of objects"
msgstr "Ομάδα αντικειμένων" msgstr "Ομάδα αντικειμένων"
#: pretix/static/pretixcontrol/js/ui/editor.js:654 #: pretix/static/pretixcontrol/js/ui/editor.js:659
msgid "Text object" msgid "Text object"
msgstr "Αντικείμενο κειμένου" msgstr "Αντικείμενο κειμένου"
#: pretix/static/pretixcontrol/js/ui/editor.js:656 #: pretix/static/pretixcontrol/js/ui/editor.js:661
msgid "Barcode area" msgid "Barcode area"
msgstr "Περιοχή Barcode" msgstr "Περιοχή Barcode"
#: pretix/static/pretixcontrol/js/ui/editor.js:658 #: pretix/static/pretixcontrol/js/ui/editor.js:663
#, fuzzy #, fuzzy
#| msgid "Barcode area" #| msgid "Barcode area"
msgid "Image area" msgid "Image area"
msgstr "Περιοχή Barcode" msgstr "Περιοχή Barcode"
#: pretix/static/pretixcontrol/js/ui/editor.js:660 #: pretix/static/pretixcontrol/js/ui/editor.js:665
msgid "Powered by pretix" msgid "Powered by pretix"
msgstr "Υποστηρίζεται από το Pretix" msgstr "Υποστηρίζεται από το Pretix"
#: pretix/static/pretixcontrol/js/ui/editor.js:662 #: pretix/static/pretixcontrol/js/ui/editor.js:667
msgid "Object" msgid "Object"
msgstr "Αντικείμενο" msgstr "Αντικείμενο"
#: pretix/static/pretixcontrol/js/ui/editor.js:666 #: pretix/static/pretixcontrol/js/ui/editor.js:671
msgid "Ticket design" msgid "Ticket design"
msgstr "Σχεδιασμός εισιτηρίων" msgstr "Σχεδιασμός εισιτηρίων"
#: pretix/static/pretixcontrol/js/ui/editor.js:956 #: pretix/static/pretixcontrol/js/ui/editor.js:961
msgid "Saving failed." msgid "Saving failed."
msgstr "Η αποθήκευση απέτυχε." msgstr "Η αποθήκευση απέτυχε."
#: pretix/static/pretixcontrol/js/ui/editor.js:1006 #: pretix/static/pretixcontrol/js/ui/editor.js:1011
#: pretix/static/pretixcontrol/js/ui/editor.js:1045 #: pretix/static/pretixcontrol/js/ui/editor.js:1050
msgid "Error while uploading your PDF file, please try again." msgid "Error while uploading your PDF file, please try again."
msgstr "Σφάλμα κατά τη μεταφόρτωση του αρχείου PDF, δοκιμάστε ξανά." msgstr "Σφάλμα κατά τη μεταφόρτωση του αρχείου PDF, δοκιμάστε ξανά."
#: pretix/static/pretixcontrol/js/ui/editor.js:1030 #: pretix/static/pretixcontrol/js/ui/editor.js:1035
msgid "Do you really want to leave the editor without saving your changes?" msgid "Do you really want to leave the editor without saving your changes?"
msgstr "" msgstr ""
"Θέλετε πραγματικά να αφήσετε τον επεξεργαστή χωρίς να αποθηκεύσετε τις " "Θέλετε πραγματικά να αφήσετε τον επεξεργαστή χωρίς να αποθηκεύσετε τις "
@@ -677,40 +677,40 @@ msgid_plural "The items in your cart are reserved for you for {num} minutes."
msgstr[0] "Τα είδη στο καλάθι θα παραμείνουν δεσμευμένα για ένα λεπτό." msgstr[0] "Τα είδη στο καλάθι θα παραμείνουν δεσμευμένα για ένα λεπτό."
msgstr[1] "Τα είδη στο καλάθι θα παραμείνουν δεσμευμένα για {num} λεπτά." msgstr[1] "Τα είδη στο καλάθι θα παραμείνουν δεσμευμένα για {num} λεπτά."
#: pretix/static/pretixpresale/js/ui/main.js:144 #: pretix/static/pretixpresale/js/ui/main.js:152
#, fuzzy #, fuzzy
#| msgctxt "widget" #| msgctxt "widget"
#| msgid "from %(currency)s %(price)s" #| msgid "from %(currency)s %(price)s"
msgid "The organizer keeps %(currency)s %(amount)s" msgid "The organizer keeps %(currency)s %(amount)s"
msgstr "απο %(currency)s %(price)s" msgstr "απο %(currency)s %(price)s"
#: pretix/static/pretixpresale/js/ui/main.js:152 #: pretix/static/pretixpresale/js/ui/main.js:160
#, fuzzy #, fuzzy
#| msgctxt "widget" #| msgctxt "widget"
#| msgid "from %(currency)s %(price)s" #| msgid "from %(currency)s %(price)s"
msgid "You get %(currency)s %(amount)s back" msgid "You get %(currency)s %(amount)s back"
msgstr "απο %(currency)s %(price)s" msgstr "απο %(currency)s %(price)s"
#: pretix/static/pretixpresale/js/ui/main.js:168 #: pretix/static/pretixpresale/js/ui/main.js:176
msgid "Please enter the amount the organizer can keep." msgid "Please enter the amount the organizer can keep."
msgstr "" msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:380 #: pretix/static/pretixpresale/js/ui/main.js:388
msgid "Please enter a quantity for one of the ticket types." msgid "Please enter a quantity for one of the ticket types."
msgstr "Εισαγάγετε μια ποσότητα για έναν από τους τύπους εισιτηρίων." msgstr "Εισαγάγετε μια ποσότητα για έναν από τους τύπους εισιτηρίων."
#: pretix/static/pretixpresale/js/ui/main.js:416 #: pretix/static/pretixpresale/js/ui/main.js:424
#, fuzzy #, fuzzy
#| msgid "Cart expired" #| msgid "Cart expired"
msgid "required" msgid "required"
msgstr "Το καλάθι έληξε" msgstr "Το καλάθι έληξε"
#: pretix/static/pretixpresale/js/ui/main.js:519 #: pretix/static/pretixpresale/js/ui/main.js:527
#: pretix/static/pretixpresale/js/ui/main.js:538 #: pretix/static/pretixpresale/js/ui/main.js:546
msgid "Time zone:" msgid "Time zone:"
msgstr "" msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:529 #: pretix/static/pretixpresale/js/ui/main.js:537
msgid "Your local time:" msgid "Your local time:"
msgstr "" msgstr ""
File diff suppressed because it is too large Load Diff
+24 -24
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-10-11 09:30+0000\n" "POT-Creation-Date: 2022-11-21 14:52+0000\n"
"PO-Revision-Date: 2021-11-25 21:00+0000\n" "PO-Revision-Date: 2021-11-25 21:00+0000\n"
"Last-Translator: Ismael Menéndez Fernández <ismael.menendez@balidea.com>\n" "Last-Translator: Ismael Menéndez Fernández <ismael.menendez@balidea.com>\n"
"Language-Team: Spanish <https://translate.pretix.eu/projects/pretix/pretix-" "Language-Team: Spanish <https://translate.pretix.eu/projects/pretix/pretix-"
@@ -131,18 +131,18 @@ msgstr ""
msgid "Mercado Pago" msgid "Mercado Pago"
msgstr "" msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:157 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:163
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:48 #: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:48
msgid "Continue" msgid "Continue"
msgstr "Continuar" msgstr "Continuar"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:215 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:221
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:152 #: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:152
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:183 #: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:183
msgid "Confirming your payment …" msgid "Confirming your payment …"
msgstr "Confirmando el pago…" msgstr "Confirmando el pago…"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:240 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:246
msgid "Payment method unavailable" msgid "Payment method unavailable"
msgstr "" msgstr ""
@@ -483,51 +483,51 @@ msgstr "minutos"
msgid "Check-in QR" msgid "Check-in QR"
msgstr "QR de Chequeo" msgstr "QR de Chequeo"
#: pretix/static/pretixcontrol/js/ui/editor.js:378 #: pretix/static/pretixcontrol/js/ui/editor.js:384
msgid "The PDF background file could not be loaded for the following reason:" msgid "The PDF background file could not be loaded for the following reason:"
msgstr "" msgstr ""
"El archivo PDF de fondo no ha podido ser cargado debido al siguiente motivo:" "El archivo PDF de fondo no ha podido ser cargado debido al siguiente motivo:"
#: pretix/static/pretixcontrol/js/ui/editor.js:648 #: pretix/static/pretixcontrol/js/ui/editor.js:653
msgid "Group of objects" msgid "Group of objects"
msgstr "Grupo de objetos" msgstr "Grupo de objetos"
#: pretix/static/pretixcontrol/js/ui/editor.js:654 #: pretix/static/pretixcontrol/js/ui/editor.js:659
msgid "Text object" msgid "Text object"
msgstr "Objeto de texto" msgstr "Objeto de texto"
#: pretix/static/pretixcontrol/js/ui/editor.js:656 #: pretix/static/pretixcontrol/js/ui/editor.js:661
msgid "Barcode area" msgid "Barcode area"
msgstr "Área para código de barras" msgstr "Área para código de barras"
#: pretix/static/pretixcontrol/js/ui/editor.js:658 #: pretix/static/pretixcontrol/js/ui/editor.js:663
msgid "Image area" msgid "Image area"
msgstr "Área de imagen" msgstr "Área de imagen"
#: pretix/static/pretixcontrol/js/ui/editor.js:660 #: pretix/static/pretixcontrol/js/ui/editor.js:665
msgid "Powered by pretix" msgid "Powered by pretix"
msgstr "Proveído por pretix" msgstr "Proveído por pretix"
#: pretix/static/pretixcontrol/js/ui/editor.js:662 #: pretix/static/pretixcontrol/js/ui/editor.js:667
msgid "Object" msgid "Object"
msgstr "Objeto" msgstr "Objeto"
#: pretix/static/pretixcontrol/js/ui/editor.js:666 #: pretix/static/pretixcontrol/js/ui/editor.js:671
msgid "Ticket design" msgid "Ticket design"
msgstr "Diseño del ticket" msgstr "Diseño del ticket"
#: pretix/static/pretixcontrol/js/ui/editor.js:956 #: pretix/static/pretixcontrol/js/ui/editor.js:961
msgid "Saving failed." msgid "Saving failed."
msgstr "El guardado falló." msgstr "El guardado falló."
#: pretix/static/pretixcontrol/js/ui/editor.js:1006 #: pretix/static/pretixcontrol/js/ui/editor.js:1011
#: pretix/static/pretixcontrol/js/ui/editor.js:1045 #: pretix/static/pretixcontrol/js/ui/editor.js:1050
msgid "Error while uploading your PDF file, please try again." msgid "Error while uploading your PDF file, please try again."
msgstr "" msgstr ""
"Ha habido un error mientras se cargaba el archivo PDF, por favor, intente de " "Ha habido un error mientras se cargaba el archivo PDF, por favor, intente de "
"nuevo." "nuevo."
#: pretix/static/pretixcontrol/js/ui/editor.js:1030 #: pretix/static/pretixcontrol/js/ui/editor.js:1035
msgid "Do you really want to leave the editor without saving your changes?" msgid "Do you really want to leave the editor without saving your changes?"
msgstr "¿Realmente desea salir del editor sin haber guardado sus cambios?" msgstr "¿Realmente desea salir del editor sin haber guardado sus cambios?"
@@ -637,32 +637,32 @@ msgstr[0] ""
msgstr[1] "" msgstr[1] ""
"Los elementos en su carrito de compras se han reservado por {num} minutos." "Los elementos en su carrito de compras se han reservado por {num} minutos."
#: pretix/static/pretixpresale/js/ui/main.js:144 #: pretix/static/pretixpresale/js/ui/main.js:152
msgid "The organizer keeps %(currency)s %(amount)s" msgid "The organizer keeps %(currency)s %(amount)s"
msgstr "El organizador se queda %(currency)s %(price)s" msgstr "El organizador se queda %(currency)s %(price)s"
#: pretix/static/pretixpresale/js/ui/main.js:152 #: pretix/static/pretixpresale/js/ui/main.js:160
msgid "You get %(currency)s %(amount)s back" msgid "You get %(currency)s %(amount)s back"
msgstr "Obtienes %(currency)s %(price)s de vuelta" msgstr "Obtienes %(currency)s %(price)s de vuelta"
#: pretix/static/pretixpresale/js/ui/main.js:168 #: pretix/static/pretixpresale/js/ui/main.js:176
msgid "Please enter the amount the organizer can keep." msgid "Please enter the amount the organizer can keep."
msgstr "Por favor, ingrese el monto que el organizador puede quedarse." msgstr "Por favor, ingrese el monto que el organizador puede quedarse."
#: pretix/static/pretixpresale/js/ui/main.js:380 #: pretix/static/pretixpresale/js/ui/main.js:388
msgid "Please enter a quantity for one of the ticket types." msgid "Please enter a quantity for one of the ticket types."
msgstr "Por favor, introduzca un valor para cada tipo de entrada." msgstr "Por favor, introduzca un valor para cada tipo de entrada."
#: pretix/static/pretixpresale/js/ui/main.js:416 #: pretix/static/pretixpresale/js/ui/main.js:424
msgid "required" msgid "required"
msgstr "campo requerido" msgstr "campo requerido"
#: pretix/static/pretixpresale/js/ui/main.js:519 #: pretix/static/pretixpresale/js/ui/main.js:527
#: pretix/static/pretixpresale/js/ui/main.js:538 #: pretix/static/pretixpresale/js/ui/main.js:546
msgid "Time zone:" msgid "Time zone:"
msgstr "Zona horaria:" msgstr "Zona horaria:"
#: pretix/static/pretixpresale/js/ui/main.js:529 #: pretix/static/pretixpresale/js/ui/main.js:537
msgid "Your local time:" msgid "Your local time:"
msgstr "Su hora local:" msgstr "Su hora local:"
File diff suppressed because it is too large Load Diff
+24 -24
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-10-11 09:30+0000\n" "POT-Creation-Date: 2022-11-21 14:52+0000\n"
"PO-Revision-Date: 2021-11-10 05:00+0000\n" "PO-Revision-Date: 2021-11-10 05:00+0000\n"
"Last-Translator: Jaakko Rinta-Filppula <jaakko@r-f.fi>\n" "Last-Translator: Jaakko Rinta-Filppula <jaakko@r-f.fi>\n"
"Language-Team: Finnish <https://translate.pretix.eu/projects/pretix/pretix-" "Language-Team: Finnish <https://translate.pretix.eu/projects/pretix/pretix-"
@@ -131,7 +131,7 @@ msgstr ""
msgid "Mercado Pago" msgid "Mercado Pago"
msgstr "" msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:157 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:163
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:48 #: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:48
#, fuzzy #, fuzzy
#| msgctxt "widget" #| msgctxt "widget"
@@ -139,13 +139,13 @@ msgstr ""
msgid "Continue" msgid "Continue"
msgstr "Jatka" msgstr "Jatka"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:215 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:221
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:152 #: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:152
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:183 #: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:183
msgid "Confirming your payment …" msgid "Confirming your payment …"
msgstr "Maksuasi vahvistetaan …" msgstr "Maksuasi vahvistetaan …"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:240 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:246
msgid "Payment method unavailable" msgid "Payment method unavailable"
msgstr "" msgstr ""
@@ -487,50 +487,50 @@ msgstr ""
msgid "Check-in QR" msgid "Check-in QR"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:378 #: pretix/static/pretixcontrol/js/ui/editor.js:384
msgid "The PDF background file could not be loaded for the following reason:" msgid "The PDF background file could not be loaded for the following reason:"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:648 #: pretix/static/pretixcontrol/js/ui/editor.js:653
msgid "Group of objects" msgid "Group of objects"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:654 #: pretix/static/pretixcontrol/js/ui/editor.js:659
msgid "Text object" msgid "Text object"
msgstr "Tekstiobjekti" msgstr "Tekstiobjekti"
#: pretix/static/pretixcontrol/js/ui/editor.js:656 #: pretix/static/pretixcontrol/js/ui/editor.js:661
msgid "Barcode area" msgid "Barcode area"
msgstr "Viivakoodialue" msgstr "Viivakoodialue"
#: pretix/static/pretixcontrol/js/ui/editor.js:658 #: pretix/static/pretixcontrol/js/ui/editor.js:663
#, fuzzy #, fuzzy
#| msgid "Barcode area" #| msgid "Barcode area"
msgid "Image area" msgid "Image area"
msgstr "Viivakoodialue" msgstr "Viivakoodialue"
#: pretix/static/pretixcontrol/js/ui/editor.js:660 #: pretix/static/pretixcontrol/js/ui/editor.js:665
msgid "Powered by pretix" msgid "Powered by pretix"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:662 #: pretix/static/pretixcontrol/js/ui/editor.js:667
msgid "Object" msgid "Object"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:666 #: pretix/static/pretixcontrol/js/ui/editor.js:671
msgid "Ticket design" msgid "Ticket design"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:956 #: pretix/static/pretixcontrol/js/ui/editor.js:961
msgid "Saving failed." msgid "Saving failed."
msgstr "Tallennus epäonnistui." msgstr "Tallennus epäonnistui."
#: pretix/static/pretixcontrol/js/ui/editor.js:1006 #: pretix/static/pretixcontrol/js/ui/editor.js:1011
#: pretix/static/pretixcontrol/js/ui/editor.js:1045 #: pretix/static/pretixcontrol/js/ui/editor.js:1050
msgid "Error while uploading your PDF file, please try again." msgid "Error while uploading your PDF file, please try again."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:1030 #: pretix/static/pretixcontrol/js/ui/editor.js:1035
msgid "Do you really want to leave the editor without saving your changes?" msgid "Do you really want to leave the editor without saving your changes?"
msgstr "" msgstr ""
@@ -636,34 +636,34 @@ msgid_plural "The items in your cart are reserved for you for {num} minutes."
msgstr[0] "Ostoskorissasi olevat tuotteet eivät ole enää varattu sinulle." msgstr[0] "Ostoskorissasi olevat tuotteet eivät ole enää varattu sinulle."
msgstr[1] "Ostoskorissasi olevat tuotteet eivät ole enää varattu sinulle." msgstr[1] "Ostoskorissasi olevat tuotteet eivät ole enää varattu sinulle."
#: pretix/static/pretixpresale/js/ui/main.js:144 #: pretix/static/pretixpresale/js/ui/main.js:152
msgid "The organizer keeps %(currency)s %(amount)s" msgid "The organizer keeps %(currency)s %(amount)s"
msgstr "" msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:152 #: pretix/static/pretixpresale/js/ui/main.js:160
msgid "You get %(currency)s %(amount)s back" msgid "You get %(currency)s %(amount)s back"
msgstr "" msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:168 #: pretix/static/pretixpresale/js/ui/main.js:176
msgid "Please enter the amount the organizer can keep." msgid "Please enter the amount the organizer can keep."
msgstr "" msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:380 #: pretix/static/pretixpresale/js/ui/main.js:388
msgid "Please enter a quantity for one of the ticket types." msgid "Please enter a quantity for one of the ticket types."
msgstr "" msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:416 #: pretix/static/pretixpresale/js/ui/main.js:424
#, fuzzy #, fuzzy
#| msgid "Cart expired" #| msgid "Cart expired"
msgid "required" msgid "required"
msgstr "Ostoskori on vanhentunut" msgstr "Ostoskori on vanhentunut"
#: pretix/static/pretixpresale/js/ui/main.js:519 #: pretix/static/pretixpresale/js/ui/main.js:527
#: pretix/static/pretixpresale/js/ui/main.js:538 #: pretix/static/pretixpresale/js/ui/main.js:546
msgid "Time zone:" msgid "Time zone:"
msgstr "Aikavyöhyke:" msgstr "Aikavyöhyke:"
#: pretix/static/pretixpresale/js/ui/main.js:529 #: pretix/static/pretixpresale/js/ui/main.js:537
msgid "Your local time:" msgid "Your local time:"
msgstr "" msgstr ""
File diff suppressed because it is too large Load Diff
+24 -24
View File
@@ -6,7 +6,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: French\n" "Project-Id-Version: French\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-10-11 09:30+0000\n" "POT-Creation-Date: 2022-11-21 14:52+0000\n"
"PO-Revision-Date: 2022-04-07 10:40+0000\n" "PO-Revision-Date: 2022-04-07 10:40+0000\n"
"Last-Translator: Eva-Maria Obermann <obermann@rami.io>\n" "Last-Translator: Eva-Maria Obermann <obermann@rami.io>\n"
"Language-Team: French <https://translate.pretix.eu/projects/pretix/pretix-js/" "Language-Team: French <https://translate.pretix.eu/projects/pretix/pretix-js/"
@@ -130,7 +130,7 @@ msgstr ""
msgid "Mercado Pago" msgid "Mercado Pago"
msgstr "" msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:157 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:163
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:48 #: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:48
#, fuzzy #, fuzzy
#| msgctxt "widget" #| msgctxt "widget"
@@ -138,13 +138,13 @@ msgstr ""
msgid "Continue" msgid "Continue"
msgstr "Continuer" msgstr "Continuer"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:215 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:221
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:152 #: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:152
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:183 #: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:183
msgid "Confirming your payment …" msgid "Confirming your payment …"
msgstr "Confirmation de votre paiment…" msgstr "Confirmation de votre paiment…"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:240 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:246
msgid "Payment method unavailable" msgid "Payment method unavailable"
msgstr "" msgstr ""
@@ -511,53 +511,53 @@ msgstr ""
msgid "Check-in QR" msgid "Check-in QR"
msgstr "Enregistrement QR code" msgstr "Enregistrement QR code"
#: pretix/static/pretixcontrol/js/ui/editor.js:378 #: pretix/static/pretixcontrol/js/ui/editor.js:384
msgid "The PDF background file could not be loaded for the following reason:" msgid "The PDF background file could not be loaded for the following reason:"
msgstr "" msgstr ""
"Le fichier PDF généré en arrière-plan n'a pas pu être chargé pour la raison " "Le fichier PDF généré en arrière-plan n'a pas pu être chargé pour la raison "
"suivante :" "suivante :"
#: pretix/static/pretixcontrol/js/ui/editor.js:648 #: pretix/static/pretixcontrol/js/ui/editor.js:653
msgid "Group of objects" msgid "Group of objects"
msgstr "Groupe d'objets" msgstr "Groupe d'objets"
#: pretix/static/pretixcontrol/js/ui/editor.js:654 #: pretix/static/pretixcontrol/js/ui/editor.js:659
msgid "Text object" msgid "Text object"
msgstr "Objet texte" msgstr "Objet texte"
#: pretix/static/pretixcontrol/js/ui/editor.js:656 #: pretix/static/pretixcontrol/js/ui/editor.js:661
msgid "Barcode area" msgid "Barcode area"
msgstr "Zone de code-barres" msgstr "Zone de code-barres"
#: pretix/static/pretixcontrol/js/ui/editor.js:658 #: pretix/static/pretixcontrol/js/ui/editor.js:663
#, fuzzy #, fuzzy
#| msgid "Barcode area" #| msgid "Barcode area"
msgid "Image area" msgid "Image area"
msgstr "Zone de code-barres" msgstr "Zone de code-barres"
#: pretix/static/pretixcontrol/js/ui/editor.js:660 #: pretix/static/pretixcontrol/js/ui/editor.js:665
msgid "Powered by pretix" msgid "Powered by pretix"
msgstr "Propulsé par pretix" msgstr "Propulsé par pretix"
#: pretix/static/pretixcontrol/js/ui/editor.js:662 #: pretix/static/pretixcontrol/js/ui/editor.js:667
msgid "Object" msgid "Object"
msgstr "Objet" msgstr "Objet"
#: pretix/static/pretixcontrol/js/ui/editor.js:666 #: pretix/static/pretixcontrol/js/ui/editor.js:671
msgid "Ticket design" msgid "Ticket design"
msgstr "Conception des billets" msgstr "Conception des billets"
#: pretix/static/pretixcontrol/js/ui/editor.js:956 #: pretix/static/pretixcontrol/js/ui/editor.js:961
msgid "Saving failed." msgid "Saving failed."
msgstr "L'enregistrement a échoué." msgstr "L'enregistrement a échoué."
#: pretix/static/pretixcontrol/js/ui/editor.js:1006 #: pretix/static/pretixcontrol/js/ui/editor.js:1011
#: pretix/static/pretixcontrol/js/ui/editor.js:1045 #: pretix/static/pretixcontrol/js/ui/editor.js:1050
msgid "Error while uploading your PDF file, please try again." msgid "Error while uploading your PDF file, please try again."
msgstr "" msgstr ""
"Erreur lors du téléchargement de votre fichier PDF, veuillez réessayer." "Erreur lors du téléchargement de votre fichier PDF, veuillez réessayer."
#: pretix/static/pretixcontrol/js/ui/editor.js:1030 #: pretix/static/pretixcontrol/js/ui/editor.js:1035
msgid "Do you really want to leave the editor without saving your changes?" msgid "Do you really want to leave the editor without saving your changes?"
msgstr "" msgstr ""
"Voulez-vous vraiment quitter l'éditeur sans sauvegarder vos modifications ?" "Voulez-vous vraiment quitter l'éditeur sans sauvegarder vos modifications ?"
@@ -665,40 +665,40 @@ msgid_plural "The items in your cart are reserved for you for {num} minutes."
msgstr[0] "Les articles de votre panier sont réservés pour une minute." msgstr[0] "Les articles de votre panier sont réservés pour une minute."
msgstr[1] "Les articles de votre panier sont réservés pendant {num} minutes." msgstr[1] "Les articles de votre panier sont réservés pendant {num} minutes."
#: pretix/static/pretixpresale/js/ui/main.js:144 #: pretix/static/pretixpresale/js/ui/main.js:152
#, fuzzy #, fuzzy
#| msgctxt "widget" #| msgctxt "widget"
#| msgid "from %(currency)s %(price)s" #| msgid "from %(currency)s %(price)s"
msgid "The organizer keeps %(currency)s %(amount)s" msgid "The organizer keeps %(currency)s %(amount)s"
msgstr "de %(currency)s %(price)s" msgstr "de %(currency)s %(price)s"
#: pretix/static/pretixpresale/js/ui/main.js:152 #: pretix/static/pretixpresale/js/ui/main.js:160
#, fuzzy #, fuzzy
#| msgctxt "widget" #| msgctxt "widget"
#| msgid "from %(currency)s %(price)s" #| msgid "from %(currency)s %(price)s"
msgid "You get %(currency)s %(amount)s back" msgid "You get %(currency)s %(amount)s back"
msgstr "de %(currency)s %(price)s" msgstr "de %(currency)s %(price)s"
#: pretix/static/pretixpresale/js/ui/main.js:168 #: pretix/static/pretixpresale/js/ui/main.js:176
msgid "Please enter the amount the organizer can keep." msgid "Please enter the amount the organizer can keep."
msgstr "" msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:380 #: pretix/static/pretixpresale/js/ui/main.js:388
msgid "Please enter a quantity for one of the ticket types." msgid "Please enter a quantity for one of the ticket types."
msgstr "SVP entrez une quantité pour un de vos types de billets." msgstr "SVP entrez une quantité pour un de vos types de billets."
#: pretix/static/pretixpresale/js/ui/main.js:416 #: pretix/static/pretixpresale/js/ui/main.js:424
#, fuzzy #, fuzzy
#| msgid "Cart expired" #| msgid "Cart expired"
msgid "required" msgid "required"
msgstr "Panier expiré" msgstr "Panier expiré"
#: pretix/static/pretixpresale/js/ui/main.js:519 #: pretix/static/pretixpresale/js/ui/main.js:527
#: pretix/static/pretixpresale/js/ui/main.js:538 #: pretix/static/pretixpresale/js/ui/main.js:546
msgid "Time zone:" msgid "Time zone:"
msgstr "" msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:529 #: pretix/static/pretixpresale/js/ui/main.js:537
msgid "Your local time:" msgid "Your local time:"
msgstr "" msgstr ""
File diff suppressed because it is too large Load Diff
+24 -24
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-10-11 09:30+0000\n" "POT-Creation-Date: 2022-11-21 14:52+0000\n"
"PO-Revision-Date: 2022-02-22 22:00+0000\n" "PO-Revision-Date: 2022-02-22 22:00+0000\n"
"Last-Translator: Ismael Menéndez Fernández <ismael.menendez@balidea.com>\n" "Last-Translator: Ismael Menéndez Fernández <ismael.menendez@balidea.com>\n"
"Language-Team: Galician <https://translate.pretix.eu/projects/pretix/pretix-" "Language-Team: Galician <https://translate.pretix.eu/projects/pretix/pretix-"
@@ -131,18 +131,18 @@ msgstr ""
msgid "Mercado Pago" msgid "Mercado Pago"
msgstr "" msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:157 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:163
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:48 #: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:48
msgid "Continue" msgid "Continue"
msgstr "Continuar" msgstr "Continuar"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:215 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:221
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:152 #: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:152
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:183 #: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:183
msgid "Confirming your payment …" msgid "Confirming your payment …"
msgstr "Confirmando o pagamento…" msgstr "Confirmando o pagamento…"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:240 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:246
msgid "Payment method unavailable" msgid "Payment method unavailable"
msgstr "" msgstr ""
@@ -483,49 +483,49 @@ msgstr "minutos"
msgid "Check-in QR" msgid "Check-in QR"
msgstr "QR de validación" msgstr "QR de validación"
#: pretix/static/pretixcontrol/js/ui/editor.js:378 #: pretix/static/pretixcontrol/js/ui/editor.js:384
msgid "The PDF background file could not be loaded for the following reason:" msgid "The PDF background file could not be loaded for the following reason:"
msgstr "O arquivo PDF de fondo non se puido cargar polo motivo seguinte:" msgstr "O arquivo PDF de fondo non se puido cargar polo motivo seguinte:"
#: pretix/static/pretixcontrol/js/ui/editor.js:648 #: pretix/static/pretixcontrol/js/ui/editor.js:653
msgid "Group of objects" msgid "Group of objects"
msgstr "Grupo de obxectos" msgstr "Grupo de obxectos"
#: pretix/static/pretixcontrol/js/ui/editor.js:654 #: pretix/static/pretixcontrol/js/ui/editor.js:659
msgid "Text object" msgid "Text object"
msgstr "Obxecto de texto" msgstr "Obxecto de texto"
#: pretix/static/pretixcontrol/js/ui/editor.js:656 #: pretix/static/pretixcontrol/js/ui/editor.js:661
msgid "Barcode area" msgid "Barcode area"
msgstr "Área para código de barras" msgstr "Área para código de barras"
#: pretix/static/pretixcontrol/js/ui/editor.js:658 #: pretix/static/pretixcontrol/js/ui/editor.js:663
msgid "Image area" msgid "Image area"
msgstr "Área de imaxe" msgstr "Área de imaxe"
#: pretix/static/pretixcontrol/js/ui/editor.js:660 #: pretix/static/pretixcontrol/js/ui/editor.js:665
msgid "Powered by pretix" msgid "Powered by pretix"
msgstr "Desenvolto por Pretix" msgstr "Desenvolto por Pretix"
#: pretix/static/pretixcontrol/js/ui/editor.js:662 #: pretix/static/pretixcontrol/js/ui/editor.js:667
msgid "Object" msgid "Object"
msgstr "Obxecto" msgstr "Obxecto"
#: pretix/static/pretixcontrol/js/ui/editor.js:666 #: pretix/static/pretixcontrol/js/ui/editor.js:671
msgid "Ticket design" msgid "Ticket design"
msgstr "Deseño do tícket" msgstr "Deseño do tícket"
#: pretix/static/pretixcontrol/js/ui/editor.js:956 #: pretix/static/pretixcontrol/js/ui/editor.js:961
msgid "Saving failed." msgid "Saving failed."
msgstr "O gardado fallou." msgstr "O gardado fallou."
#: pretix/static/pretixcontrol/js/ui/editor.js:1006 #: pretix/static/pretixcontrol/js/ui/editor.js:1011
#: pretix/static/pretixcontrol/js/ui/editor.js:1045 #: pretix/static/pretixcontrol/js/ui/editor.js:1050
msgid "Error while uploading your PDF file, please try again." msgid "Error while uploading your PDF file, please try again."
msgstr "" msgstr ""
"Houbo un erro mentres se cargaba o arquivo PDF. Por favor, inténteo de novo." "Houbo un erro mentres se cargaba o arquivo PDF. Por favor, inténteo de novo."
#: pretix/static/pretixcontrol/js/ui/editor.js:1030 #: pretix/static/pretixcontrol/js/ui/editor.js:1035
msgid "Do you really want to leave the editor without saving your changes?" msgid "Do you really want to leave the editor without saving your changes?"
msgstr "Realmente desexa saír do editor sen gardar os cambios?" msgstr "Realmente desexa saír do editor sen gardar os cambios?"
@@ -634,32 +634,32 @@ msgstr[0] "Os artigos da túa cesta están reservados para ti durante un minuto.
msgstr[1] "" msgstr[1] ""
"Os artigos da túa cesta están reservados para ti durante {num} minutos." "Os artigos da túa cesta están reservados para ti durante {num} minutos."
#: pretix/static/pretixpresale/js/ui/main.js:144 #: pretix/static/pretixpresale/js/ui/main.js:152
msgid "The organizer keeps %(currency)s %(amount)s" msgid "The organizer keeps %(currency)s %(amount)s"
msgstr "O organizador queda %(currency)s %(price)s" msgstr "O organizador queda %(currency)s %(price)s"
#: pretix/static/pretixpresale/js/ui/main.js:152 #: pretix/static/pretixpresale/js/ui/main.js:160
msgid "You get %(currency)s %(amount)s back" msgid "You get %(currency)s %(amount)s back"
msgstr "Obtés %(currency)s %(price)s de volta" msgstr "Obtés %(currency)s %(price)s de volta"
#: pretix/static/pretixpresale/js/ui/main.js:168 #: pretix/static/pretixpresale/js/ui/main.js:176
msgid "Please enter the amount the organizer can keep." msgid "Please enter the amount the organizer can keep."
msgstr "Por favor, ingrese a cantidade que pode conservar o organizador." msgstr "Por favor, ingrese a cantidade que pode conservar o organizador."
#: pretix/static/pretixpresale/js/ui/main.js:380 #: pretix/static/pretixpresale/js/ui/main.js:388
msgid "Please enter a quantity for one of the ticket types." msgid "Please enter a quantity for one of the ticket types."
msgstr "Por favor, introduza un valor para cada tipo de entrada." msgstr "Por favor, introduza un valor para cada tipo de entrada."
#: pretix/static/pretixpresale/js/ui/main.js:416 #: pretix/static/pretixpresale/js/ui/main.js:424
msgid "required" msgid "required"
msgstr "campo requirido" msgstr "campo requirido"
#: pretix/static/pretixpresale/js/ui/main.js:519 #: pretix/static/pretixpresale/js/ui/main.js:527
#: pretix/static/pretixpresale/js/ui/main.js:538 #: pretix/static/pretixpresale/js/ui/main.js:546
msgid "Time zone:" msgid "Time zone:"
msgstr "Zona horaria:" msgstr "Zona horaria:"
#: pretix/static/pretixpresale/js/ui/main.js:529 #: pretix/static/pretixpresale/js/ui/main.js:537
msgid "Your local time:" msgid "Your local time:"
msgstr "A súa hora local:" msgstr "A súa hora local:"
File diff suppressed because it is too large Load Diff
+24 -24
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-10-11 09:30+0000\n" "POT-Creation-Date: 2022-11-21 14:52+0000\n"
"PO-Revision-Date: 2021-09-24 13:54+0000\n" "PO-Revision-Date: 2021-09-24 13:54+0000\n"
"Last-Translator: ofirtro <ofir.tro@gmail.com>\n" "Last-Translator: ofirtro <ofir.tro@gmail.com>\n"
"Language-Team: Hebrew <https://translate.pretix.eu/projects/pretix/pretix-js/" "Language-Team: Hebrew <https://translate.pretix.eu/projects/pretix/pretix-js/"
@@ -130,18 +130,18 @@ msgstr ""
msgid "Mercado Pago" msgid "Mercado Pago"
msgstr "" msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:157 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:163
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:48 #: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:48
msgid "Continue" msgid "Continue"
msgstr "המשך" msgstr "המשך"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:215 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:221
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:152 #: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:152
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:183 #: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:183
msgid "Confirming your payment …" msgid "Confirming your payment …"
msgstr "מאמת את התשלום שלך…" msgstr "מאמת את התשלום שלך…"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:240 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:246
msgid "Payment method unavailable" msgid "Payment method unavailable"
msgstr "" msgstr ""
@@ -472,48 +472,48 @@ msgstr ""
msgid "Check-in QR" msgid "Check-in QR"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:378 #: pretix/static/pretixcontrol/js/ui/editor.js:384
msgid "The PDF background file could not be loaded for the following reason:" msgid "The PDF background file could not be loaded for the following reason:"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:648 #: pretix/static/pretixcontrol/js/ui/editor.js:653
msgid "Group of objects" msgid "Group of objects"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:654 #: pretix/static/pretixcontrol/js/ui/editor.js:659
msgid "Text object" msgid "Text object"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:656 #: pretix/static/pretixcontrol/js/ui/editor.js:661
msgid "Barcode area" msgid "Barcode area"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:658 #: pretix/static/pretixcontrol/js/ui/editor.js:663
msgid "Image area" msgid "Image area"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:660 #: pretix/static/pretixcontrol/js/ui/editor.js:665
msgid "Powered by pretix" msgid "Powered by pretix"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:662 #: pretix/static/pretixcontrol/js/ui/editor.js:667
msgid "Object" msgid "Object"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:666 #: pretix/static/pretixcontrol/js/ui/editor.js:671
msgid "Ticket design" msgid "Ticket design"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:956 #: pretix/static/pretixcontrol/js/ui/editor.js:961
msgid "Saving failed." msgid "Saving failed."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:1006 #: pretix/static/pretixcontrol/js/ui/editor.js:1011
#: pretix/static/pretixcontrol/js/ui/editor.js:1045 #: pretix/static/pretixcontrol/js/ui/editor.js:1050
msgid "Error while uploading your PDF file, please try again." msgid "Error while uploading your PDF file, please try again."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:1030 #: pretix/static/pretixcontrol/js/ui/editor.js:1035
msgid "Do you really want to leave the editor without saving your changes?" msgid "Do you really want to leave the editor without saving your changes?"
msgstr "" msgstr ""
@@ -619,32 +619,32 @@ msgstr[1] ""
msgstr[2] "" msgstr[2] ""
msgstr[3] "" msgstr[3] ""
#: pretix/static/pretixpresale/js/ui/main.js:144 #: pretix/static/pretixpresale/js/ui/main.js:152
msgid "The organizer keeps %(currency)s %(amount)s" msgid "The organizer keeps %(currency)s %(amount)s"
msgstr "" msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:152 #: pretix/static/pretixpresale/js/ui/main.js:160
msgid "You get %(currency)s %(amount)s back" msgid "You get %(currency)s %(amount)s back"
msgstr "" msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:168 #: pretix/static/pretixpresale/js/ui/main.js:176
msgid "Please enter the amount the organizer can keep." msgid "Please enter the amount the organizer can keep."
msgstr "" msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:380 #: pretix/static/pretixpresale/js/ui/main.js:388
msgid "Please enter a quantity for one of the ticket types." msgid "Please enter a quantity for one of the ticket types."
msgstr "" msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:416 #: pretix/static/pretixpresale/js/ui/main.js:424
msgid "required" msgid "required"
msgstr "" msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:519 #: pretix/static/pretixpresale/js/ui/main.js:527
#: pretix/static/pretixpresale/js/ui/main.js:538 #: pretix/static/pretixpresale/js/ui/main.js:546
msgid "Time zone:" msgid "Time zone:"
msgstr "" msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:529 #: pretix/static/pretixpresale/js/ui/main.js:537
msgid "Your local time:" msgid "Your local time:"
msgstr "" msgstr ""
File diff suppressed because it is too large Load Diff
+24 -24
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-10-11 09:30+0000\n" "POT-Creation-Date: 2022-11-21 14:52+0000\n"
"PO-Revision-Date: 2020-01-24 08:00+0000\n" "PO-Revision-Date: 2020-01-24 08:00+0000\n"
"Last-Translator: Prokaj Miklós <mixolid0@gmail.com>\n" "Last-Translator: Prokaj Miklós <mixolid0@gmail.com>\n"
"Language-Team: Hungarian <https://translate.pretix.eu/projects/pretix/pretix-" "Language-Team: Hungarian <https://translate.pretix.eu/projects/pretix/pretix-"
@@ -131,7 +131,7 @@ msgstr ""
msgid "Mercado Pago" msgid "Mercado Pago"
msgstr "" msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:157 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:163
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:48 #: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:48
#, fuzzy #, fuzzy
#| msgctxt "widget" #| msgctxt "widget"
@@ -139,13 +139,13 @@ msgstr ""
msgid "Continue" msgid "Continue"
msgstr "Folytatás" msgstr "Folytatás"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:215 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:221
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:152 #: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:152
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:183 #: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:183
msgid "Confirming your payment …" msgid "Confirming your payment …"
msgstr "A fizetés megerősítése…" msgstr "A fizetés megerősítése…"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:240 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:246
msgid "Payment method unavailable" msgid "Payment method unavailable"
msgstr "" msgstr ""
@@ -511,50 +511,50 @@ msgstr ""
msgid "Check-in QR" msgid "Check-in QR"
msgstr "Check in QR" msgstr "Check in QR"
#: pretix/static/pretixcontrol/js/ui/editor.js:378 #: pretix/static/pretixcontrol/js/ui/editor.js:384
msgid "The PDF background file could not be loaded for the following reason:" msgid "The PDF background file could not be loaded for the following reason:"
msgstr "A PDF háttér fájl nem tölthető be a következők miatt:" msgstr "A PDF háttér fájl nem tölthető be a következők miatt:"
#: pretix/static/pretixcontrol/js/ui/editor.js:648 #: pretix/static/pretixcontrol/js/ui/editor.js:653
msgid "Group of objects" msgid "Group of objects"
msgstr "tárgy csoport" msgstr "tárgy csoport"
#: pretix/static/pretixcontrol/js/ui/editor.js:654 #: pretix/static/pretixcontrol/js/ui/editor.js:659
msgid "Text object" msgid "Text object"
msgstr "Szöveg" msgstr "Szöveg"
#: pretix/static/pretixcontrol/js/ui/editor.js:656 #: pretix/static/pretixcontrol/js/ui/editor.js:661
msgid "Barcode area" msgid "Barcode area"
msgstr "Vonalkód terület" msgstr "Vonalkód terület"
#: pretix/static/pretixcontrol/js/ui/editor.js:658 #: pretix/static/pretixcontrol/js/ui/editor.js:663
#, fuzzy #, fuzzy
#| msgid "Barcode area" #| msgid "Barcode area"
msgid "Image area" msgid "Image area"
msgstr "Vonalkód terület" msgstr "Vonalkód terület"
#: pretix/static/pretixcontrol/js/ui/editor.js:660 #: pretix/static/pretixcontrol/js/ui/editor.js:665
msgid "Powered by pretix" msgid "Powered by pretix"
msgstr "pretix által működtetett" msgstr "pretix által működtetett"
#: pretix/static/pretixcontrol/js/ui/editor.js:662 #: pretix/static/pretixcontrol/js/ui/editor.js:667
msgid "Object" msgid "Object"
msgstr "objektum" msgstr "objektum"
#: pretix/static/pretixcontrol/js/ui/editor.js:666 #: pretix/static/pretixcontrol/js/ui/editor.js:671
msgid "Ticket design" msgid "Ticket design"
msgstr "Jegy design" msgstr "Jegy design"
#: pretix/static/pretixcontrol/js/ui/editor.js:956 #: pretix/static/pretixcontrol/js/ui/editor.js:961
msgid "Saving failed." msgid "Saving failed."
msgstr "Mentés sikertelen." msgstr "Mentés sikertelen."
#: pretix/static/pretixcontrol/js/ui/editor.js:1006 #: pretix/static/pretixcontrol/js/ui/editor.js:1011
#: pretix/static/pretixcontrol/js/ui/editor.js:1045 #: pretix/static/pretixcontrol/js/ui/editor.js:1050
msgid "Error while uploading your PDF file, please try again." msgid "Error while uploading your PDF file, please try again."
msgstr "Hiba a PDF fájl feltöltése közben, próbálja újra." msgstr "Hiba a PDF fájl feltöltése közben, próbálja újra."
#: pretix/static/pretixcontrol/js/ui/editor.js:1030 #: pretix/static/pretixcontrol/js/ui/editor.js:1035
msgid "Do you really want to leave the editor without saving your changes?" msgid "Do you really want to leave the editor without saving your changes?"
msgstr "Biztosan ki akar lépni a szerkesztőből a változtatások mentése nélkül?" msgstr "Biztosan ki akar lépni a szerkesztőből a változtatások mentése nélkül?"
@@ -665,40 +665,40 @@ msgid_plural "The items in your cart are reserved for you for {num} minutes."
msgstr[0] "A kosár tartalma egy percig foglalva van számodra." msgstr[0] "A kosár tartalma egy percig foglalva van számodra."
msgstr[1] "A kosár tartalma {num} percig foglalva van számodra." msgstr[1] "A kosár tartalma {num} percig foglalva van számodra."
#: pretix/static/pretixpresale/js/ui/main.js:144 #: pretix/static/pretixpresale/js/ui/main.js:152
#, fuzzy #, fuzzy
#| msgctxt "widget" #| msgctxt "widget"
#| msgid "from %(currency)s %(price)s" #| msgid "from %(currency)s %(price)s"
msgid "The organizer keeps %(currency)s %(amount)s" msgid "The organizer keeps %(currency)s %(amount)s"
msgstr "%(currency) %(price)-tól" msgstr "%(currency) %(price)-tól"
#: pretix/static/pretixpresale/js/ui/main.js:152 #: pretix/static/pretixpresale/js/ui/main.js:160
#, fuzzy #, fuzzy
#| msgctxt "widget" #| msgctxt "widget"
#| msgid "from %(currency)s %(price)s" #| msgid "from %(currency)s %(price)s"
msgid "You get %(currency)s %(amount)s back" msgid "You get %(currency)s %(amount)s back"
msgstr "%(currency) %(price)-tól" msgstr "%(currency) %(price)-tól"
#: pretix/static/pretixpresale/js/ui/main.js:168 #: pretix/static/pretixpresale/js/ui/main.js:176
msgid "Please enter the amount the organizer can keep." msgid "Please enter the amount the organizer can keep."
msgstr "" msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:380 #: pretix/static/pretixpresale/js/ui/main.js:388
msgid "Please enter a quantity for one of the ticket types." msgid "Please enter a quantity for one of the ticket types."
msgstr "Adjon meg egy mennyiséget az egyik jegytípusból." msgstr "Adjon meg egy mennyiséget az egyik jegytípusból."
#: pretix/static/pretixpresale/js/ui/main.js:416 #: pretix/static/pretixpresale/js/ui/main.js:424
#, fuzzy #, fuzzy
#| msgid "Cart expired" #| msgid "Cart expired"
msgid "required" msgid "required"
msgstr "A kosár lejárt" msgstr "A kosár lejárt"
#: pretix/static/pretixpresale/js/ui/main.js:519 #: pretix/static/pretixpresale/js/ui/main.js:527
#: pretix/static/pretixpresale/js/ui/main.js:538 #: pretix/static/pretixpresale/js/ui/main.js:546
msgid "Time zone:" msgid "Time zone:"
msgstr "" msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:529 #: pretix/static/pretixpresale/js/ui/main.js:537
msgid "Your local time:" msgid "Your local time:"
msgstr "" msgstr ""
File diff suppressed because it is too large Load Diff
+24 -24
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-10-11 09:30+0000\n" "POT-Creation-Date: 2022-11-21 14:52+0000\n"
"PO-Revision-Date: 2022-05-08 19:00+0000\n" "PO-Revision-Date: 2022-05-08 19:00+0000\n"
"Last-Translator: Emanuele Signoretta <signorettae@gmail.com>\n" "Last-Translator: Emanuele Signoretta <signorettae@gmail.com>\n"
"Language-Team: Italian <https://translate.pretix.eu/projects/pretix/pretix-" "Language-Team: Italian <https://translate.pretix.eu/projects/pretix/pretix-"
@@ -133,18 +133,18 @@ msgstr ""
msgid "Mercado Pago" msgid "Mercado Pago"
msgstr "" msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:157 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:163
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:48 #: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:48
msgid "Continue" msgid "Continue"
msgstr "Continua" msgstr "Continua"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:215 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:221
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:152 #: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:152
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:183 #: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:183
msgid "Confirming your payment …" msgid "Confirming your payment …"
msgstr "Stiamo processando il tuo pagamento …" msgstr "Stiamo processando il tuo pagamento …"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:240 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:246
msgid "Payment method unavailable" msgid "Payment method unavailable"
msgstr "" msgstr ""
@@ -485,48 +485,48 @@ msgstr "minuti"
msgid "Check-in QR" msgid "Check-in QR"
msgstr "Check-in con QR" msgstr "Check-in con QR"
#: pretix/static/pretixcontrol/js/ui/editor.js:378 #: pretix/static/pretixcontrol/js/ui/editor.js:384
msgid "The PDF background file could not be loaded for the following reason:" msgid "The PDF background file could not be loaded for the following reason:"
msgstr "Il file PDF di sfondo non può essere caricato per le seguenti ragioni:" msgstr "Il file PDF di sfondo non può essere caricato per le seguenti ragioni:"
#: pretix/static/pretixcontrol/js/ui/editor.js:648 #: pretix/static/pretixcontrol/js/ui/editor.js:653
msgid "Group of objects" msgid "Group of objects"
msgstr "Gruppo di oggetti" msgstr "Gruppo di oggetti"
#: pretix/static/pretixcontrol/js/ui/editor.js:654 #: pretix/static/pretixcontrol/js/ui/editor.js:659
msgid "Text object" msgid "Text object"
msgstr "Oggetto testo" msgstr "Oggetto testo"
#: pretix/static/pretixcontrol/js/ui/editor.js:656 #: pretix/static/pretixcontrol/js/ui/editor.js:661
msgid "Barcode area" msgid "Barcode area"
msgstr "Area codice a barra" msgstr "Area codice a barra"
#: pretix/static/pretixcontrol/js/ui/editor.js:658 #: pretix/static/pretixcontrol/js/ui/editor.js:663
msgid "Image area" msgid "Image area"
msgstr "Area immagini" msgstr "Area immagini"
#: pretix/static/pretixcontrol/js/ui/editor.js:660 #: pretix/static/pretixcontrol/js/ui/editor.js:665
msgid "Powered by pretix" msgid "Powered by pretix"
msgstr "Powered by Pretix" msgstr "Powered by Pretix"
#: pretix/static/pretixcontrol/js/ui/editor.js:662 #: pretix/static/pretixcontrol/js/ui/editor.js:667
msgid "Object" msgid "Object"
msgstr "Oggetto" msgstr "Oggetto"
#: pretix/static/pretixcontrol/js/ui/editor.js:666 #: pretix/static/pretixcontrol/js/ui/editor.js:671
msgid "Ticket design" msgid "Ticket design"
msgstr "Design biglietto" msgstr "Design biglietto"
#: pretix/static/pretixcontrol/js/ui/editor.js:956 #: pretix/static/pretixcontrol/js/ui/editor.js:961
msgid "Saving failed." msgid "Saving failed."
msgstr "Salvataggio fallito." msgstr "Salvataggio fallito."
#: pretix/static/pretixcontrol/js/ui/editor.js:1006 #: pretix/static/pretixcontrol/js/ui/editor.js:1011
#: pretix/static/pretixcontrol/js/ui/editor.js:1045 #: pretix/static/pretixcontrol/js/ui/editor.js:1050
msgid "Error while uploading your PDF file, please try again." msgid "Error while uploading your PDF file, please try again."
msgstr "Errore durante il caricamento del tuo file PDF, prova di nuovo." msgstr "Errore durante il caricamento del tuo file PDF, prova di nuovo."
#: pretix/static/pretixcontrol/js/ui/editor.js:1030 #: pretix/static/pretixcontrol/js/ui/editor.js:1035
msgid "Do you really want to leave the editor without saving your changes?" msgid "Do you really want to leave the editor without saving your changes?"
msgstr "Vuoi davvero abbandonare l'editor senza salvare le modifiche?" msgstr "Vuoi davvero abbandonare l'editor senza salvare le modifiche?"
@@ -632,32 +632,32 @@ msgid_plural "The items in your cart are reserved for you for {num} minutes."
msgstr[0] "Gli elementi nel tuo carrello sono riservati per 1 minuto." msgstr[0] "Gli elementi nel tuo carrello sono riservati per 1 minuto."
msgstr[1] "Gli elementi nel tuo carrello sono riservati per {num} minuti." msgstr[1] "Gli elementi nel tuo carrello sono riservati per {num} minuti."
#: pretix/static/pretixpresale/js/ui/main.js:144 #: pretix/static/pretixpresale/js/ui/main.js:152
msgid "The organizer keeps %(currency)s %(amount)s" msgid "The organizer keeps %(currency)s %(amount)s"
msgstr "L'organizzatore trattiene %(currency)s %(amount)s" msgstr "L'organizzatore trattiene %(currency)s %(amount)s"
#: pretix/static/pretixpresale/js/ui/main.js:152 #: pretix/static/pretixpresale/js/ui/main.js:160
msgid "You get %(currency)s %(amount)s back" msgid "You get %(currency)s %(amount)s back"
msgstr "Ricevi indietro %(currency)s %(amount)s" msgstr "Ricevi indietro %(currency)s %(amount)s"
#: pretix/static/pretixpresale/js/ui/main.js:168 #: pretix/static/pretixpresale/js/ui/main.js:176
msgid "Please enter the amount the organizer can keep." msgid "Please enter the amount the organizer can keep."
msgstr "Inserisci l'importo che l'organizzatore può trattenere." msgstr "Inserisci l'importo che l'organizzatore può trattenere."
#: pretix/static/pretixpresale/js/ui/main.js:380 #: pretix/static/pretixpresale/js/ui/main.js:388
msgid "Please enter a quantity for one of the ticket types." msgid "Please enter a quantity for one of the ticket types."
msgstr "Inserisci la quantità per una tipologia di biglietto." msgstr "Inserisci la quantità per una tipologia di biglietto."
#: pretix/static/pretixpresale/js/ui/main.js:416 #: pretix/static/pretixpresale/js/ui/main.js:424
msgid "required" msgid "required"
msgstr "richiesto" msgstr "richiesto"
#: pretix/static/pretixpresale/js/ui/main.js:519 #: pretix/static/pretixpresale/js/ui/main.js:527
#: pretix/static/pretixpresale/js/ui/main.js:538 #: pretix/static/pretixpresale/js/ui/main.js:546
msgid "Time zone:" msgid "Time zone:"
msgstr "Fuso orario:" msgstr "Fuso orario:"
#: pretix/static/pretixpresale/js/ui/main.js:529 #: pretix/static/pretixpresale/js/ui/main.js:537
msgid "Your local time:" msgid "Your local time:"
msgstr "Ora locale:" msgstr "Ora locale:"
File diff suppressed because it is too large Load Diff
+24 -24
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-10-11 09:30+0000\n" "POT-Creation-Date: 2022-11-21 14:52+0000\n"
"PO-Revision-Date: 2022-03-15 00:00+0000\n" "PO-Revision-Date: 2022-03-15 00:00+0000\n"
"Last-Translator: Yuriko Matsunami <y.matsunami@enobyte.com>\n" "Last-Translator: Yuriko Matsunami <y.matsunami@enobyte.com>\n"
"Language-Team: Japanese <https://translate.pretix.eu/projects/pretix/pretix-" "Language-Team: Japanese <https://translate.pretix.eu/projects/pretix/pretix-"
@@ -131,18 +131,18 @@ msgstr ""
msgid "Mercado Pago" msgid "Mercado Pago"
msgstr "" msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:157 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:163
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:48 #: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:48
msgid "Continue" msgid "Continue"
msgstr "次へ" msgstr "次へ"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:215 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:221
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:152 #: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:152
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:183 #: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:183
msgid "Confirming your payment …" msgid "Confirming your payment …"
msgstr "お支払い内容の確認" msgstr "お支払い内容の確認"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:240 #: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:246
msgid "Payment method unavailable" msgid "Payment method unavailable"
msgstr "" msgstr ""
@@ -482,48 +482,48 @@ msgstr "分"
msgid "Check-in QR" msgid "Check-in QR"
msgstr "チェックイン用QRコード" msgstr "チェックイン用QRコード"
#: pretix/static/pretixcontrol/js/ui/editor.js:378 #: pretix/static/pretixcontrol/js/ui/editor.js:384
msgid "The PDF background file could not be loaded for the following reason:" msgid "The PDF background file could not be loaded for the following reason:"
msgstr "以下の理由によりPDFファイルの読み込みに失敗しました:" msgstr "以下の理由によりPDFファイルの読み込みに失敗しました:"
#: pretix/static/pretixcontrol/js/ui/editor.js:648 #: pretix/static/pretixcontrol/js/ui/editor.js:653
msgid "Group of objects" msgid "Group of objects"
msgstr "オブジェクトグループ" msgstr "オブジェクトグループ"
#: pretix/static/pretixcontrol/js/ui/editor.js:654 #: pretix/static/pretixcontrol/js/ui/editor.js:659
msgid "Text object" msgid "Text object"
msgstr "テキストオブジェクト" msgstr "テキストオブジェクト"
#: pretix/static/pretixcontrol/js/ui/editor.js:656 #: pretix/static/pretixcontrol/js/ui/editor.js:661
msgid "Barcode area" msgid "Barcode area"
msgstr "バーコードエリア" msgstr "バーコードエリア"
#: pretix/static/pretixcontrol/js/ui/editor.js:658 #: pretix/static/pretixcontrol/js/ui/editor.js:663
msgid "Image area" msgid "Image area"
msgstr "画像エリア" msgstr "画像エリア"
#: pretix/static/pretixcontrol/js/ui/editor.js:660 #: pretix/static/pretixcontrol/js/ui/editor.js:665
msgid "Powered by pretix" msgid "Powered by pretix"
msgstr "Pretixのイベントチケット売り場" msgstr "Pretixのイベントチケット売り場"
#: pretix/static/pretixcontrol/js/ui/editor.js:662 #: pretix/static/pretixcontrol/js/ui/editor.js:667
msgid "Object" msgid "Object"
msgstr "オブジェクト" msgstr "オブジェクト"
#: pretix/static/pretixcontrol/js/ui/editor.js:666 #: pretix/static/pretixcontrol/js/ui/editor.js:671
msgid "Ticket design" msgid "Ticket design"
msgstr "チケットのデザイン" msgstr "チケットのデザイン"
#: pretix/static/pretixcontrol/js/ui/editor.js:956 #: pretix/static/pretixcontrol/js/ui/editor.js:961
msgid "Saving failed." msgid "Saving failed."
msgstr "保存できませんでした。" msgstr "保存できませんでした。"
#: pretix/static/pretixcontrol/js/ui/editor.js:1006 #: pretix/static/pretixcontrol/js/ui/editor.js:1011
#: pretix/static/pretixcontrol/js/ui/editor.js:1045 #: pretix/static/pretixcontrol/js/ui/editor.js:1050
msgid "Error while uploading your PDF file, please try again." msgid "Error while uploading your PDF file, please try again."
msgstr "PDFのアップロード中に問題が発生しました。再試行してください。" msgstr "PDFのアップロード中に問題が発生しました。再試行してください。"
#: pretix/static/pretixcontrol/js/ui/editor.js:1030 #: pretix/static/pretixcontrol/js/ui/editor.js:1035
msgid "Do you really want to leave the editor without saving your changes?" msgid "Do you really want to leave the editor without saving your changes?"
msgstr "変更内容を保存せずに編集を終了しますか?" msgstr "変更内容を保存せずに編集を終了しますか?"
@@ -627,32 +627,32 @@ msgid "The items in your cart are reserved for you for one minute."
msgid_plural "The items in your cart are reserved for you for {num} minutes." msgid_plural "The items in your cart are reserved for you for {num} minutes."
msgstr[0] "カート内の商品の予約は {num} 分以内に完了します。" msgstr[0] "カート内の商品の予約は {num} 分以内に完了します。"
#: pretix/static/pretixpresale/js/ui/main.js:144 #: pretix/static/pretixpresale/js/ui/main.js:152
msgid "The organizer keeps %(currency)s %(amount)s" msgid "The organizer keeps %(currency)s %(amount)s"
msgstr "主催者には%(currency)s %(amount)sが与えられます" msgstr "主催者には%(currency)s %(amount)sが与えられます"
#: pretix/static/pretixpresale/js/ui/main.js:152 #: pretix/static/pretixpresale/js/ui/main.js:160
msgid "You get %(currency)s %(amount)s back" msgid "You get %(currency)s %(amount)s back"
msgstr "%(currency)s %(amount)s が払い戻されます" msgstr "%(currency)s %(amount)s が払い戻されます"
#: pretix/static/pretixpresale/js/ui/main.js:168 #: pretix/static/pretixpresale/js/ui/main.js:176
msgid "Please enter the amount the organizer can keep." msgid "Please enter the amount the organizer can keep."
msgstr "イベント開催者が受け取る料金を入力してください。" msgstr "イベント開催者が受け取る料金を入力してください。"
#: pretix/static/pretixpresale/js/ui/main.js:380 #: pretix/static/pretixpresale/js/ui/main.js:388
msgid "Please enter a quantity for one of the ticket types." msgid "Please enter a quantity for one of the ticket types."
msgstr "商品の総数を入力してください。" msgstr "商品の総数を入力してください。"
#: pretix/static/pretixpresale/js/ui/main.js:416 #: pretix/static/pretixpresale/js/ui/main.js:424
msgid "required" msgid "required"
msgstr "必須" msgstr "必須"
#: pretix/static/pretixpresale/js/ui/main.js:519 #: pretix/static/pretixpresale/js/ui/main.js:527
#: pretix/static/pretixpresale/js/ui/main.js:538 #: pretix/static/pretixpresale/js/ui/main.js:546
msgid "Time zone:" msgid "Time zone:"
msgstr "タイムゾーン:" msgstr "タイムゾーン:"
#: pretix/static/pretixpresale/js/ui/main.js:529 #: pretix/static/pretixpresale/js/ui/main.js:537
msgid "Your local time:" msgid "Your local time:"
msgstr "現地時間:" msgstr "現地時間:"
File diff suppressed because it is too large Load Diff

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