Compare commits

..
Author SHA1 Message Date
dependabot[bot] 913e950cb6 Update pyjwt requirement from ==2.13.* to ==2.14.*
Updates the requirements on [pyjwt](https://github.com/jpadilla/pyjwt) to permit the latest version.
- [Release notes](https://github.com/jpadilla/pyjwt/releases)
- [Changelog](https://github.com/jpadilla/pyjwt/blob/master/CHANGELOG.rst)
- [Commits](https://github.com/jpadilla/pyjwt/compare/2.13.0...2.14.0)

---
updated-dependencies:
- dependency-name: pyjwt
  dependency-version: 2.14.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-14 18:13:40 +00:00
Richard Schreiber 689b99c3aa PDF: fix inline merge_background on fg_pdf instead of its own PdfWriter (#6555)
* PDF: fix inline merge_background on fg_pdf instead of its own PdfWriter

* fix pdf_header

* fix flake8
2026-09-14 15:45:54 +02:00
Raphael Michel 6c40daa863 Hotfix for JS issue when submit() is called from JS 2026-09-14 15:33:25 +02:00
dependabot[bot]andRaphael Michel efdc83f72a Update pypdf requirement from ==6.5.* to ==6.11.* (#6176)
* Update pypdf requirement from ==6.5.* to ==6.11.*

Updates the requirements on [pypdf](https://github.com/py-pdf/pypdf) to permit the latest version.
- [Release notes](https://github.com/py-pdf/pypdf/releases)
- [Changelog](https://github.com/py-pdf/pypdf/blob/main/CHANGELOG.md)
- [Commits](https://github.com/py-pdf/pypdf/compare/6.5.0...6.11.0)

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

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

* Try to adjust code

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Raphael Michel <michel@rami.io>
2026-09-14 14:09:28 +02:00
dependabot[bot] 8b10534c74 Bump smol-toml from 1.6.1 to 1.7.1 (#6546)
Bumps [smol-toml](https://github.com/squirrelchat/smol-toml) from 1.6.1 to 1.7.1.
- [Release notes](https://github.com/squirrelchat/smol-toml/releases)
- [Commits](https://github.com/squirrelchat/smol-toml/compare/v1.6.1...v1.7.1)

---
updated-dependencies:
- dependency-name: smol-toml
  dependency-version: 1.7.1
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-14 10:31:12 +02:00
Raphael Michel bcacff2ee7 Voucher list: Add budget and budget used to CSV export (Z#23237857) (#6520)
* Voucher list: Add budget and budget used to CSV export (Z#23237857)

* Fix failing test
2026-09-14 10:31:07 +02:00
Kara Engelhardt 47096f7f1b sendmail: fix query performance when filtering on checkin (Z#23244045) 2026-09-14 10:24:58 +02:00
Raphael Michel c240ebcb8e Force Django update 2026-09-14 09:51:32 +02:00
Raphael Michel ce3e59e020 PDF reports: Fix headers for overlong event names (Z#23239566) (#6521) 2026-09-14 09:38:44 +02:00
Raphael Michel 4a9da40028 [A11y] Form JavaScript: Support for <button formnovalidate> (#6536) 2026-09-14 09:38:34 +02:00
Raphael Michelandpajowu eab1efd5f4 Phone number input: Fix workaround for prefixes shared between countries (fixes #6544) (#6545)
* Phone number input: Fix workaround for prefixes shared between countries (fixes #6544)

* Update src/pretix/base/forms/questions.py

Co-authored-by: pajowu <engelhardt@pretix.eu>

---------

Co-authored-by: pajowu <engelhardt@pretix.eu>
2026-09-14 09:35:32 +02:00
Richard Schreiber c7290b614e Show payment-QR-codes on mobile (#6503) 2026-09-14 08:50:45 +02:00
Raphael Michel 1aea5633eb Discounts: Fix ManyToMany fields when cloning (#6547) 2026-09-11 18:35:37 +02:00
Richard Schreiber 86cc719651 Widget: serve vite by default, origin-whitelist for vue2 (#6403) 2026-09-11 08:53:42 +02:00
Mira Weller 742a69f09f Add git-blame-ignore-revs file (see #6541) 2026-09-10 12:54:51 +02:00
Yasunobu YesNo Kawaguchi c05dee7af5 Translations: Update Japanese
Currently translated at 100.0% (6419 of 6419 strings)

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

powered by weblate
2026-09-10 12:36:49 +02:00
Albizuri e399a49c8b Translations: Update Basque
Currently translated at 48.0% (3086 of 6419 strings)

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

powered by weblate
2026-09-10 12:36:49 +02:00
Linnea Thelander b9b951e56b Translations: Update Swedish
Currently translated at 98.0% (255 of 260 strings)

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

powered by weblate
2026-09-10 12:36:49 +02:00
Linnea Thelander 88bb1f4008 Translations: Update Swedish
Currently translated at 85.8% (5509 of 6419 strings)

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

powered by weblate
2026-09-10 12:36:49 +02:00
Renne Rocha 24e7db7ddd Translations: Update Portuguese (Brazil)
Currently translated at 92.4% (5937 of 6419 strings)

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

powered by weblate
2026-09-10 12:36:49 +02:00
Hijiri Umemoto 96ed6fe1a6 Translations: Update Japanese
Currently translated at 100.0% (6419 of 6419 strings)

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

powered by weblate
2026-09-10 12:36:49 +02:00
23 changed files with 156 additions and 169 deletions
+2
View File
@@ -0,0 +1,2 @@
# Format pre-vue code with eslint where possible (2026-09-10)
d85e52c83ed3639e040372fd0052e842e4899d90
+3 -3
View File
@@ -4148,9 +4148,9 @@
}
},
"node_modules/smol-toml": {
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.6.1.tgz",
"integrity": "sha512-dWUG8F5sIIARXih1DTaQAX4SsiTXhInKf1buxdY9DIg4ZYPZK5nGM1VRIYmEbDbsHt7USo99xSLFu5Q1IqTmsg==",
"version": "1.7.1",
"resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.7.1.tgz",
"integrity": "sha512-PPlsspAZ4jbMBu5DMFhfUGDQLu/vrL4SyBROVS37x8ynnVmFIs1VPBz1Co8Xks3TvpIaZXmU85y4DrQ+UyVFoQ==",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
+3 -3
View File
@@ -37,7 +37,7 @@ dependencies = [
"css-inline==0.21.*",
"defusedcsv>=3.0.0",
"dnspython==2.*",
"Django[argon2]==5.2.*",
"Django[argon2]==5.2.*,>=5.2.17",
"django-bootstrap3==26.2",
"django-compressor==4.6.0",
"django-countries==9.0.*",
@@ -75,7 +75,7 @@ dependencies = [
"packaging",
"paypalrestsdk==1.13.*",
"paypal-checkout-serversdk==1.0.*",
"PyJWT==2.13.*",
"PyJWT==2.14.*",
"phonenumberslite==9.0.*",
"Pillow==12.3.*",
"pretix-plugin-build",
@@ -84,7 +84,7 @@ dependencies = [
"pycountry",
"pycparser==3.0",
"pycryptodome==3.23.*",
"pypdf==6.5.*",
"pypdf==6.11.*",
"python-bidi==0.6.*", # Support for Arabic in reportlab
"python-dateutil==2.9.*",
"pytz",
+10 -4
View File
@@ -350,16 +350,22 @@ class WrappedPhonePrefixSelect(Select):
return super().render(name, value or self.initial, *args, **kwargs)
def get_context(self, name, value, attrs):
if value and self.choices[1][0] != value:
matching_choices = len([1 for p, c in self.choices if p == value])
# self.choices is lazy evaluated, needs to be realized to be modifiable
choices = list(self.choices)
if value and choices[1][0] != value:
matching_choices = len([1 for p, c in choices if p == value])
if matching_choices > 1:
# Some countries share a phone prefix, for example +1 is used all over the Americas.
# This causes a UX problem: If the default value or the existing data is +12125552368,
# the widget will just show the first <option> entry with value="+1" as selected,
# which alphabetically is America Samoa, although most numbers statistically are from
# the US. As a workaround, we detect this case and add an aditional choice value with
# the US. As a workaround, we detect this case and add an additional choice value with
# just <option value="+1">+1</option> without an explicit country.
self.choices.insert(1, (value, value))
self.choices = [
choices[0],
(value, value),
*choices[1:],
]
context = super().get_context(name, value, attrs)
return context
+16 -25
View File
@@ -1232,9 +1232,7 @@ class Renderer:
for i, page in enumerate(fg_pdf.pages):
bg_page = self.bg_pdf.pages[i]
_correct_page_media_box(bg_page)
page.merge_page(bg_page, over=False)
output.add_page(page)
_merge_with_correct_page_media_box(output, page, bg_page)
# pdf_header is a string like "%pdf-X.X"
if float(self.bg_pdf.pdf_header[5:]) > float(fg_pdf.pdf_header[5:]):
@@ -1299,39 +1297,32 @@ def merge_background(fg_pdf: PdfWriter, bg_pdf: PdfWriter, out_file, compress):
bg_pdf.write(bg_filename)
subprocess.run(pdftk_cmd, check=True, stdout=out_file)
else:
output = PdfWriter()
for i, page in enumerate(fg_pdf.pages):
bg_page = bg_pdf.pages[i]
_correct_page_media_box(bg_page)
page.merge_page(bg_page, over=False)
_merge_with_correct_page_media_box(output, page, bg_page)
# pdf_header is a string like "%pdf-X.X"
if float(bg_pdf.pdf_header[5:]) > float(fg_pdf.pdf_header[5:]):
fg_pdf.pdf_header = bg_pdf.pdf_header
fg_pdf.write(out_file)
output.pdf_header = (
bg_pdf.pdf_header
if float(bg_pdf.pdf_header[5:]) > float(fg_pdf.pdf_header[5:])
else fg_pdf.pdf_header
)
output.write(out_file)
def _correct_page_media_box(page: pypdf.PageObject):
if page.rotation != 0:
page.transfer_rotation_to_content()
media_box = page.mediabox
def _merge_with_correct_page_media_box(output: pypdf.PdfWriter, fg_page: pypdf.PageObject, bg_page: pypdf.PageObject):
if bg_page.rotation != 0:
bg_page.transfer_rotation_to_content()
media_box = bg_page.mediabox
trsf = pypdf.Transformation()
if media_box.bottom != 0:
trsf = trsf.translate(0, -media_box.bottom)
if media_box.left != 0:
trsf = trsf.translate(-media_box.left, 0)
page.add_transformation(trsf, False)
for b in ["/MediaBox", "/CropBox", "/BleedBox", "/TrimBox", "/ArtBox"]:
if b in page:
rr = pypdf.generic.RectangleObject(page[b])
pt1 = trsf.apply_on(rr.lower_left)
pt2 = trsf.apply_on(rr.upper_right)
page[pypdf.generic.NameObject(b)] = pypdf.generic.RectangleObject((
min(pt1[0], pt2[0]),
min(pt1[1], pt2[1]),
max(pt1[0], pt2[0]),
max(pt1[1], pt2[1]),
))
fg_page = output.add_page(fg_page)
fg_page.merge_transformed_page(bg_page, trsf, over=False, expand=False)
@deconstructible
File diff suppressed because one or more lines are too long
+3 -3
View File
@@ -105,12 +105,12 @@ class GlobalSettingsForm(SettingsForm):
domain=settings.SITE_URL
)
)),
('widget_vite_origins', forms.CharField(
('widget_vue2_origins', forms.CharField(
widget=forms.Textarea(attrs={'rows': '3'}),
required=False,
# Not translated on purpose, this is a temporary feature and contains too many special case words
label="Vite widget origins",
help_text="One origin per line (e.g. https://example.com). Requests from these origins will be served the new vite-based widget.",
label="Vue2 widget origins",
help_text="One origin per line (e.g. https://example.com). Requests from these origins will be served the old vue2-based widget.",
))
])
responses = register_global_settings.send(self)
+4 -2
View File
@@ -144,7 +144,7 @@ class VoucherList(VoucherQueryMixin, PaginationMixin, EventPermissionRequiredMix
headers = [
_('Voucher code'), _('Valid until'), _('Product'), _('Reserve quota'), _('Bypass quota'),
_('Price effect'), _('Value'), _('Tag'), _('Redeemed'), _('Maximum usages'), _('Seat'),
_('Comment')
_('Comment'), _('Budget'), _('Budget used')
]
writer.writerow(headers)
@@ -170,7 +170,9 @@ class VoucherList(VoucherQueryMixin, PaginationMixin, EventPermissionRequiredMix
str(v.redeemed),
str(v.max_usages),
str(v.seat) if v.seat else "",
str(v.comment) if v.comment else ""
str(v.comment) if v.comment else "",
str(v.budget) if v.budget is not None else "",
str(v.budget_used) if v.budget is not None else "",
]
writer.writerow(row)
+7 -7
View File
@@ -8,16 +8,16 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-08-24 15:35+0000\n"
"PO-Revision-Date: 2026-08-24 14:30+0000\n"
"PO-Revision-Date: 2026-09-04 14:29+0000\n"
"Last-Translator: Albizuri <oier@puntu.eus>\n"
"Language-Team: Basque <https://translate.pretix.eu/projects/pretix/pretix/eu/"
">\n"
"Language-Team: Basque <https://translate.pretix.eu/projects/pretix/pretix/"
"eu/>\n"
"Language: eu\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 2026.8.1\n"
"X-Generator: Weblate 2026.9\n"
#: pretix/_base_settings.py
msgid "English"
@@ -891,7 +891,7 @@ msgstr "Produktuaren data"
#: pretix/control/templates/pretixcontrol/order/index.html
#: pretix/presale/templates/pretixpresale/event/order.html
msgid "Order details"
msgstr ""
msgstr "Eskaeraren xehetasunak"
#: pretix/base/datasync/sourcefields.py pretix/base/modelimport_orders.py
#: pretix/control/forms/filter.py
@@ -17296,7 +17296,7 @@ msgstr ""
#: pretix/control/logdisplay.py
msgid "The order details have been changed."
msgstr ""
msgstr "Eskaeraren xehetasunak aldatu dira."
#: pretix/control/logdisplay.py
msgid "The order has been marked as unpaid."
@@ -23106,7 +23106,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/order/index.html
#, python-format
msgid "Order details: %(code)s"
msgstr ""
msgstr "Eskaeraren xehetasunak: %(code)s"
#: pretix/control/templates/pretixcontrol/order/index.html
#: pretix/control/templates/pretixcontrol/orders/index.html
+51 -70
View File
@@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-08-24 15:35+0000\n"
"PO-Revision-Date: 2026-08-16 22:00+0000\n"
"Last-Translator: Hijiri Umemoto <hijiri@umemoto.org>\n"
"PO-Revision-Date: 2026-09-07 18:00+0000\n"
"Last-Translator: Yasunobu YesNo Kawaguchi <kawaguti@gmail.com>\n"
"Language-Team: Japanese <https://translate.pretix.eu/projects/pretix/pretix/"
"ja/>\n"
"Language: ja\n"
@@ -17,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Weblate 2026.8.1\n"
"X-Generator: Weblate 2026.9\n"
#: pretix/_base_settings.py
msgid "English"
@@ -93,7 +93,7 @@ msgstr "ヘブライ語"
#: pretix/_base_settings.py
msgid "Hungarian"
msgstr ""
msgstr "ハンガリー語"
#: pretix/_base_settings.py
msgid "Indonesian"
@@ -220,7 +220,7 @@ msgstr "ターゲットURL"
#: pretix/api/models.py pretix/base/models/devices.py
#: pretix/base/models/organizer.py
msgid "All events (including newly created ones)"
msgstr "すべてのイベント(最近作成されたイベントを含む)"
msgstr "すべてのイベント(今後作成されるものを含む)"
#: pretix/api/models.py pretix/base/models/devices.py
#: pretix/base/models/organizer.py
@@ -428,10 +428,8 @@ msgid "You cannot exchange a medium for a medium."
msgstr "メディアを別のメディアに変更することはできません。"
#: pretix/api/views/checkin.py
#, fuzzy
#| msgid "Product does not support medium exchange."
msgid "You cannot simulate a medium exchange."
msgstr "本製品は中程度の交換に対応していません。"
msgstr "メディアの交換をシミュレートすることはできません。"
#: pretix/api/views/oauth.py pretix/control/logdisplay.py
#, python-brace-format
@@ -5691,7 +5689,7 @@ msgstr "国コード(ISO 3166-1 alpha-2"
#: pretix/base/models/items.py
msgid "Asked on"
msgstr ""
msgstr "質問日"
#: pretix/base/models/items.py pretix/base/models/organizer.py
msgid ""
@@ -7340,12 +7338,9 @@ msgid "The payment for this invoice has already been received."
msgstr "この請求書の支払いはすでに受領済みです。"
#: pretix/base/payment.py
#, fuzzy
#| msgid ""
#| "This payment is already being processed and can not be canceled any more."
msgid ""
"This payment is already being processed and cannot be canceled any more."
msgstr "この支払いは処理中のため、キャンセルできません。"
msgstr "この支払いはすでに処理中のため、キャンセルできません。"
#: pretix/base/payment.py
msgid "Automatic refunds are not supported by this payment provider."
@@ -8105,16 +8100,12 @@ msgid "Presale end"
msgstr "前売り終了"
#: pretix/base/reldate.py
#, fuzzy
#| msgid "Order email"
msgid "Order creation"
msgstr "注文者メール"
msgstr "注文の作成"
#: pretix/base/reldate.py
#, fuzzy
#| msgid "Order expired"
msgid "Order expiry"
msgstr "注文の有効期限が切れました"
msgstr "注文の失効"
#: pretix/base/reldate.py
msgid "before"
@@ -8143,22 +8134,22 @@ msgstr "未設定"
#: pretix/base/reldate.py
#, python-brace-format
msgid "A relative date cannot be expressed as \"before\" for \"{}\""
msgstr ""
msgstr "相対的な日付は、「{}」に対して「before」で表すことはできません"
#: pretix/base/reldate.py
#, python-brace-format
msgid "A relative date cannot be expressed as \"after\" for \"{}\""
msgstr ""
msgstr "相対的な日付は「{}」に対して「after」として表すことはできません"
#: pretix/base/reldate.py
#, python-brace-format
msgid "A relative time cannot be expressed as \"before\" for \"{}\""
msgstr ""
msgstr "相対時間は「{}」に対して「before」で表すことはできません"
#: pretix/base/reldate.py
#, python-brace-format
msgid "A relative time cannot be expressed as \"after\" for \"{}\""
msgstr ""
msgstr "相対時間は「{}」に対して「after」で表すことはできません"
#: pretix/base/secrets.py
msgid "Random (default, works with all pretix apps)"
@@ -10067,12 +10058,12 @@ msgstr ""
#: pretix/base/settings.py
msgid "No dates match your criteria."
msgstr ""
msgstr "条件に合致する日付はありません。"
#: pretix/base/settings.py
msgctxt "subevents"
msgid "Text for empty date results"
msgstr ""
msgstr "空の日付結果のテキスト"
#: pretix/base/settings.py
msgctxt "subevents"
@@ -10083,6 +10074,10 @@ msgid ""
"touch with you to arrange further dates. We do not recommend more than one "
"or two sentences."
msgstr ""
"このテキストは、カレンダーまたは日付リストが空の場合に表示されます。たとえば"
"、月に日付が含まれていない場合や、ユーザーが選択したフィルターに結果が見つか"
"らない場合です。これをご利用いただくことで、今後の日程調整のために連絡する方"
"法を宣伝できます。1文または2文以上は推奨いたしません。"
#: pretix/base/settings.py
msgid "Guidance text"
@@ -13902,26 +13897,20 @@ msgid ""
msgstr "ギフトカードの有効期限を発行年を含めた{}年に設定しました。"
#: pretix/control/forms/event.py
#, fuzzy
#| msgid "Payment date"
msgid "Payment term"
msgstr "支払い日"
msgstr "支払条件"
#: pretix/control/forms/event.py
msgid "same as above"
msgstr ""
msgstr "上記と同じ"
#: pretix/control/forms/event.py
#, fuzzy
#| msgid "Payment term in days"
msgid "different payment term in days"
msgstr "支払条件(日数)"
msgstr "日数で表す異なる支払条件"
#: pretix/control/forms/event.py
#, fuzzy
#| msgid "Payment term in minutes"
msgid "different payment term in minutes"
msgstr "支払い期限(分単位)"
msgstr "分で表す異なる支払条件"
#: pretix/control/forms/event.py
msgid "Prices including tax"
@@ -22533,28 +22522,24 @@ msgstr ""
"食事を提供する場合、ユーザーに食事制限について尋ねることができる一例です。"
#: pretix/control/templates/pretixcontrol/items/questions.html
#, fuzzy
#| msgid "Create a new question"
msgid "Create a new per-ticket question"
msgstr "新しい質問を作成"
msgstr "チケットごとに新しい質問を作成"
#: pretix/control/templates/pretixcontrol/items/questions.html
#, fuzzy
#| msgid "Create a new question"
msgid "Create a new order-level question"
msgstr "新しい質問を作成"
msgstr "注文ごとに新しい質問を作成"
#: pretix/control/templates/pretixcontrol/items/questions.html
#, fuzzy
#| msgid "Delete question"
msgid "Per-ticket questions"
msgstr "質問を削除"
msgstr "チケットごとの質問"
#: pretix/control/templates/pretixcontrol/items/questions.html
msgid ""
"These questions are asked for every ticket, so possibly multiple times in "
"the same order."
msgstr ""
"これらの質問はすべてのチケットに対して尋ねられるため、同じ順序で複数回になる"
"可能性があります。"
#: pretix/control/templates/pretixcontrol/items/questions.html
msgid "Create a new question"
@@ -22573,28 +22558,24 @@ msgid "All personalized products"
msgstr "すべてのパーソナライズされた製品"
#: pretix/control/templates/pretixcontrol/items/questions.html
#, fuzzy
#| msgid "Include questions"
msgid "Per-order questions"
msgstr "質問を含む"
msgstr "注文ごとの質問"
#: pretix/control/templates/pretixcontrol/items/questions.html
msgid ""
"This functionality is in active development and expected to change "
"significantly over the coming months."
msgstr ""
msgstr "この機能は現在開発が活発で、今後数か月で大幅に変化すると予想されています。"
#: pretix/control/templates/pretixcontrol/items/questions.html
msgid ""
"Per-order questions are currently not supported and will not be displayed in "
"pretixPOS."
msgstr ""
msgstr "注文ごとの質問は現在サポートされておらず、pretixPOSでは表示されません。"
#: pretix/control/templates/pretixcontrol/items/questions.html
#, fuzzy
#| msgid "The question has been reordered."
msgid "These questions are asked once per order."
msgstr "質問の並び順が変更されました。"
msgstr "これらの質問は、注文ごとに1回ずつ尋ねられます。"
#: pretix/control/templates/pretixcontrol/items/quota.html
#: pretix/control/templates/pretixcontrol/items/quota_edit.html
@@ -23186,10 +23167,8 @@ msgstr "(任意)"
#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html
#: pretix/presale/templates/pretixpresale/event/checkout_questions.html
#: pretix/presale/templates/pretixpresale/event/order_modify.html
#, fuzzy
#| msgid "Additional information"
msgid "Additional order information"
msgstr "追加情報"
msgstr "追加の注文情報"
#: pretix/control/templates/pretixcontrol/order/delete.html
msgid "Delete order"
@@ -24856,14 +24835,13 @@ msgid "Hardware model"
msgstr "ハードウェアの機種"
#: pretix/control/templates/pretixcontrol/organizers/devices.html
#, fuzzy, python-format
#| msgid "Begin: %(time)s"
#, python-format
msgid "Last seen: %(time)s"
msgstr "開始: %(time)s"
msgstr "最後の閲覧: %(time)s"
#: pretix/control/templates/pretixcontrol/organizers/devices.html
msgid "No recent contact"
msgstr ""
msgstr "最近の連絡なし"
#: pretix/control/templates/pretixcontrol/organizers/devices.html
msgid "Not yet initialized"
@@ -28220,19 +28198,14 @@ msgstr ""
"に高いことを意味します。ドメインのDNS設定を更新すべきです。"
#: pretix/control/views/mailsetup.py
#, fuzzy
#| msgid ""
#| "We did not find DMARC record for your domain. This means that there is a "
#| "very high chance most of the emails will be rejected or marked as spam. "
#| "You should update the DNS settings of your domain."
msgid ""
"We did not find a DMARC record for your domain. This means that there is a "
"very high chance most of the emails will be rejected or marked as spam. You "
"should update the DNS settings of your domain."
msgstr ""
"お客様のドメインのDMARCレコードが見つかりませんでした。これは、ほとんどのメー"
"ルが拒否されたスパムとしてマークされたりする可能性が非常に高いことを意味し"
"す。ドメインのDNS設定を更新すべきです。"
"あなたのドメインのDMARCレコードが見つかりませんでした。これは、ほとんどの"
"メールが拒否されたスパムとしてマークされた可能性が非常に高いことを意味し"
"す。ドメインのDNS設定を更新すべきです。"
#: pretix/control/views/mailsetup.py
msgid "The verification code was incorrect, please try again."
@@ -30906,7 +30879,7 @@ msgstr ""
#: pretix/plugins/paypal2/payment.py
msgid "Allow further payments during compliance hold"
msgstr ""
msgstr "コンプライアンス保留の間、追加の支払いを許可する"
#: pretix/plugins/paypal2/payment.py
msgid ""
@@ -30916,16 +30889,20 @@ msgid ""
"attempts during that window. This might result in them being charged twice "
"if the original payment is approved."
msgstr ""
"PayPalの不正防止は、個々の支払いの処理をかなりの期間ブロックする可能性があり"
"ます。この期間中、支払いは「保留中」とマークされています。顧客がその期間中に"
"別の支払い試行を開始できるように許可することができます。元の支払いが承認され"
"た場合、二重に請求される可能性があります。"
#: pretix/plugins/paypal2/payment.py
msgid "Timeout further payment attempts"
msgstr ""
msgstr "追加の支払い試行がタイムアウト"
#: pretix/plugins/paypal2/payment.py
msgid ""
"Time duration in minutes after which another payment attempt is possible, "
"while the last payment is still under investigation."
msgstr ""
msgstr "最後の支払いがまだ調査中である間、別の支払い試行が可能となる時間(分)。"
#: pretix/plugins/paypal2/payment.py
msgid "-- Automatic --"
@@ -31190,6 +31167,10 @@ msgid ""
"twice in case PayPal allows your initial payment attempt. Please contact us "
"to resolve this case."
msgstr ""
"支払いはPayPalで処理されています。通常より時間がかかります。PayPalが支払いを"
"確認するまでお待ちいただくか、こちらまたは別の支払い方法で再度お支払いをお試"
"しください。PayPalが最初の支払い試行を許可した場合、二重に請求される可能性が"
"あります。この件を解決するために、弊社までご連絡ください。"
#: pretix/plugins/paypal2/views.py
msgid ""
+11 -6
View File
@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-08-24 15:35+0000\n"
"PO-Revision-Date: 2026-03-30 21:00+0000\n"
"PO-Revision-Date: 2026-09-02 08:35+0000\n"
"Last-Translator: Renne Rocha <renne@rocha.dev.br>\n"
"Language-Team: Portuguese (Brazil) <https://translate.pretix.eu/projects/"
"pretix/pretix/pt_BR/>\n"
@@ -17,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
"X-Generator: Weblate 5.16.2\n"
"X-Generator: Weblate 2026.8.1\n"
#: pretix/_base_settings.py
msgid "English"
@@ -93,7 +93,7 @@ msgstr "Hebraico"
#: pretix/_base_settings.py
msgid "Hungarian"
msgstr ""
msgstr "Húngaro"
#: pretix/_base_settings.py
msgid "Indonesian"
@@ -153,7 +153,7 @@ msgstr "Espanhol (América latina)"
#: pretix/_base_settings.py
msgid "Thai"
msgstr ""
msgstr "Tailandês"
#: pretix/_base_settings.py
msgid "Turkish"
@@ -3022,11 +3022,12 @@ msgid ""
"The field \"%(label)s\" may not contain special characters such as "
"\"%(chars)s\"."
msgstr ""
"O campo \"%(label)s\" não pode conter caracteres especiais como %(chars)s\"."
#: pretix/base/forms/questions.py
#, python-format
msgid "The field \"%(label)s\" may not contain an URL (%(url)s)."
msgstr ""
msgstr "O campo \"%(label)s\" não pode conter uma URL (%(url)s)."
#: pretix/base/forms/questions.py
msgctxt "phonenumber"
@@ -8173,7 +8174,7 @@ msgstr "Permitida"
#: pretix/base/permissions.py
msgctxt "permission_level"
msgid "Access existing events"
msgstr ""
msgstr "Acessar eventos existentes"
#: pretix/base/permissions.py
msgctxt "permission_level"
@@ -13607,11 +13608,15 @@ msgstr "Por favor, continue em uma nova aba"
#: pretix/base/templates/pretixbase/framebreak.html
msgid "For security reasons, the following step is only possible in a new tab."
msgstr ""
"Por razões de segurança, o passo seguinte só é possível de ser feito em uma "
"nova aba."
#: pretix/base/templates/pretixbase/framebreak.html
msgid ""
"If the new tab did not open automatically, please click the following button:"
msgstr ""
"Se uma nova aba não abrir automaticamente, por favor, clique no botão a "
"seguir:"
#: pretix/base/templates/pretixbase/framebreak.html
#: pretix/presale/templates/pretixpresale/event/cookies.html
+5 -4
View File
@@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-08-24 15:35+0000\n"
"PO-Revision-Date: 2026-08-09 06:00+0000\n"
"Last-Translator: Julien <julien@circusiloveyou.com>\n"
"PO-Revision-Date: 2026-09-04 14:29+0000\n"
"Last-Translator: Linnea Thelander <linnea@coeo.events>\n"
"Language-Team: Swedish <https://translate.pretix.eu/projects/pretix/pretix/"
"sv/>\n"
"Language: sv\n"
@@ -17,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 2026.8.1\n"
"X-Generator: Weblate 2026.9\n"
#: pretix/_base_settings.py
msgid "English"
@@ -19170,8 +19170,9 @@ msgstr ""
#: pretix/presale/templates/pretixpresale/event/order_pay.html
#: pretix/presale/templates/pretixpresale/event/order_pay_change.html
#: pretix/presale/templates/pretixpresale/event/position_change.html
#, fuzzy
msgid "Continue"
msgstr "Fortsätta"
msgstr "Fortsätt"
#: pretix/control/templates/pretixcontrol/auth/oauth_authorization.html
msgid "Authorize an application"
+5 -4
View File
@@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-06 15:52+0000\n"
"PO-Revision-Date: 2026-08-09 06:00+0000\n"
"Last-Translator: Julien <julien@circusiloveyou.com>\n"
"PO-Revision-Date: 2026-09-04 14:29+0000\n"
"Last-Translator: Linnea Thelander <linnea@coeo.events>\n"
"Language-Team: Swedish <https://translate.pretix.eu/projects/pretix/pretix-"
"js/sv/>\n"
"Language: sv\n"
@@ -17,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 2026.8.1\n"
"X-Generator: Weblate 2026.9\n"
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js
msgid "Marked as paid"
@@ -133,8 +133,9 @@ msgstr "Mercado Pago"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/i18n.ts
#: pretix/static/pretixpresale/js/ui/cart.js
#, fuzzy
msgid "Continue"
msgstr "Fortsätta"
msgstr "Fortsätt"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js
+1 -9
View File
@@ -55,7 +55,6 @@ from django.db.models.functions import Cast, Coalesce
from django.utils.timezone import make_aware
from django.utils.translation import gettext as _, gettext_lazy, pgettext_lazy
from pypdf import PageObject, PdfReader, PdfWriter, Transformation
from pypdf.generic import RectangleObject
from reportlab.lib import pagesizes
from reportlab.lib.units import inch, mm
from reportlab.pdfgen import canvas
@@ -238,15 +237,8 @@ def _render_nup_page(nup_pdf: PdfWriter, input_pages: PageObject, opt: dict) ->
di = i % badges_per_page
tx = opt['margins'][3] + (di % opt['cols']) * opt['offsets'][0]
ty = opt['margins'][2] + (opt['rows'] - 1 - (di // opt['cols'])) * opt['offsets'][1]
page.add_transformation(Transformation().translate(tx, ty))
page.mediabox = RectangleObject((
Decimal('%.5f' % (page.mediabox.left.as_numeric() + tx)),
Decimal('%.5f' % (page.mediabox.bottom.as_numeric() + ty)),
Decimal('%.5f' % (page.mediabox.right.as_numeric() + tx)),
Decimal('%.5f' % (page.mediabox.top.as_numeric() + ty))
))
page.trimbox = page.cropbox = page.mediabox
nup_page.merge_page(page)
nup_page.merge_transformed_page(page, Transformation().translate(tx, ty))
return nup_page
+15 -3
View File
@@ -55,6 +55,8 @@ from django_countries.fields import Country
from reportlab.lib import colors
from reportlab.lib.enums import TA_CENTER
from reportlab.lib.units import mm
from reportlab.lib.utils import simpleSplit
from reportlab.pdfbase.pdfmetrics import stringWidth
from reportlab.pdfgen.canvas import Canvas
from reportlab.platypus import PageBreak, Spacer, Table, TableStyle
@@ -226,10 +228,20 @@ class ReportlabExportMixin:
def page_header(self, canvas, doc):
from reportlab.lib.units import mm
canvas.setFont('OpenSans', 10)
canvas.drawString(doc.leftMargin, self.pagesize[1] - 15 * mm, self.get_left_header_string())
font_name = 'OpenSans'
font_size = 10
left_string = self.get_left_header_string()
right_string = self.get_right_header_string()
right_width = stringWidth(right_string, font_name, font_size)
max_left_width = self.pagesize[0] - doc.leftMargin - doc.rightMargin - right_width - 5 * mm
left_string_lines = simpleSplit(left_string, font_name, font_size, max_left_width)
if len(left_string_lines) > 1:
left_string = left_string_lines[0] + ""
canvas.setFont(font_name, font_size)
canvas.drawString(doc.leftMargin, self.pagesize[1] - 15 * mm, left_string)
canvas.drawRightString(self.pagesize[0] - doc.rightMargin, self.pagesize[1] - 15 * mm,
self.get_right_header_string())
right_string)
canvas.setStrokeColorRGB(0, 0, 0)
canvas.line(doc.leftMargin, self.pagesize[1] - 17 * mm,
self.pagesize[0] - doc.rightMargin, self.pagesize[1] - 17 * mm)
+2 -2
View File
@@ -355,9 +355,9 @@ class OrderSendView(BaseSenderView):
statusq |= Q(status=Order.STATUS_PENDING, require_approval=False, valid_if_pending=True)
orders = qs.filter(statusq)
opq = OrderPosition.objects.filter(
opq = OrderPosition.objects.with_scopes_disabled().filter(
Q(item_id__in=[i.pk for i in form.cleaned_data.get('items')]) | Q(Exists(
OrderPosition.objects.filter(
OrderPosition.objects.with_scopes_disabled().filter(
addon_to_id=OuterRef('pk'),
item_id__in=[i.pk for i in form.cleaned_data.get('items')]
)
@@ -3,7 +3,7 @@
{% load escapejson %}
{% if payment_qr_codes %}
<div class="tabcontainer col-md-6 col-sm-6 hidden-xs text-center js-only blank-after">
<div class="tabcontainer col-md-6 col-sm-6 col-xs-12 text-center js-only blank-after">
<div id="banktransfer_qrcodes_tabs_content" class="tabpanels blank-after">
{% for code_info in payment_qr_codes %}
<div id="banktransfer_qrcodes_{{ code_info.id }}"
+9 -8
View File
@@ -122,19 +122,20 @@ def widget_css_etag(request, version, **kwargs):
return f'{_get_source_cache_key(version)}-{request.organizer.cache.get_or_set("css_version", default=lambda: int(time.time()))}'
# use vite by default, serve old vue2-based widget only for widget_vue2_origins
def _use_vite(request):
if getattr(settings, 'PRETIX_WIDGET_VITE', False) or "beta" in request.GET:
return True
if getattr(settings, 'PRETIX_WIDGET_VUE', False) or "legacy" in request.GET:
return False
origin = request.META.get('HTTP_ORIGIN', '')
gs = GlobalSettingsObject()
vite_origins = gs.settings.get('widget_vite_origins', as_type=str, default='')
if vite_origins and not origin:
vue_origins = gs.settings.get('widget_vue2_origins', as_type=str, default='')
if vue_origins and not origin:
referer = request.META.get('HTTP_REFERER', '')
origin = '/'.join(referer.split('/', 3)[:3])
if origin and vite_origins:
origins_list = [o.strip() for o in vite_origins.strip().splitlines() if o.strip()]
return origin in origins_list
return False
if origin and vue_origins:
origins_list = [o.strip() for o in vue_origins.strip().splitlines() if o.strip()]
return origin not in origins_list
return True
def widget_js_etag(request, version, lang, **kwargs):
+1 -1
View File
@@ -913,7 +913,7 @@ VITE_DEV_SERVER_PORT = 5173
VITE_DEV_SERVER = f"http://localhost:{VITE_DEV_SERVER_PORT}"
VITE_DEV_MODE = DEBUG
VITE_IGNORE = False # Used to ignore `collectstatic`/`rebuild`
PRETIX_WIDGET_VITE = os.environ.get('PRETIX_WIDGET_VITE', '') not in ('', '0')
PRETIX_WIDGET_VUE = os.environ.get('PRETIX_WIDGET_VUE', '') not in ('', '0')
if DEBUG:
# Reload if settings file changes
@@ -233,6 +233,7 @@ let form_handlers = function (el) {
function setup_basics (el) {
el.find('form').attr('novalidate', true).on('submit', function (e) {
if (e.originalEvent && e.originalEvent.submitter && e.originalEvent.submitter.formNoValidate) return;
if (!this.checkValidity()) {
let input = this.querySelector(':invalid:not(fieldset)');
(input.labels[0] || input).scrollIntoView()
@@ -514,10 +514,6 @@ export function createWidgetStore (config: {
// button with subevent but no items
redirectUrl += `${this.subevent}/`
}
if (this.subevent && !this.cartId) {
// button with subevent but no items
redirectUrl += `${this.subevent}/`
}
redirectUrl += `?iframe=1&locale=${LANG}`
if (this.cartId) {
// ajax to make sure the cart-id is used, even if the cart is currently empty
+2 -2
View File
@@ -128,9 +128,9 @@ class VoucherFormTest(SoupTestMixin, TransactionTestCase):
doc = self.client.get('/control/event/%s/%s/vouchers/?download=yes' % (self.orga.slug, self.event.slug))
assert doc.content.decode().strip() == '"Voucher code","Valid until","Product","Reserve quota",' \
'"Bypass quota","Price effect","Value","Tag","Redeemed",' \
'"Maximum usages","Seat","Comment"' \
'"Maximum usages","Seat","Comment","Budget","Budget used"' \
'\r\n"ABCDEFG","","Early-bird ticket","No","No","No effect","","","0",' \
'"1","",""'
'"1","","","",""'
def test_filter_status_valid(self):
with scopes_disabled():
+3 -7
View File
@@ -89,11 +89,11 @@ def _widget_assets():
f'Start it with: npm run dev:widget'
)
yield
elif os.environ.get("PRETIX_WIDGET_VITE"):
elif os.environ.get("PRETIX_WIDGET_VUE"):
yield # Old widget, no build needed
else:
subprocess.check_call(['npm', 'run', 'build:widget'], cwd=PROJECT_ROOT)
yield
else:
yield # Old widget, no build needed
# ============================================================================
@@ -155,10 +155,6 @@ def live_server_url(live_server, settings):
settings.SITE_URL = live_server.url
# Enable Vite widget if requested via env var
if os.environ.get("PRETIX_WIDGET_VITE") or os.environ.get("PRETIX_WIDGET_VITE_DEV"):
settings.PRETIX_WIDGET_VITE = True
return live_server.url