Compare commits

...

16 Commits

Author SHA1 Message Date
Mira Weller
dcf15cbac1 Add unit test 2025-02-03 15:43:17 +01:00
Raphael Michel
b554fc1ad5 Invoice renderer: Group invoice lines even with addons (Z#23173618) 2025-01-13 22:04:03 +01:00
Raphael Michel
3ce6030122 PDF n-up generation: Fix ordering of badges 2025-01-07 19:32:51 +01:00
Martin Gross
28e26284a6 API: Return order-information on availability-endpoint, even if quota is unlimited 2025-01-07 17:25:39 +01:00
Raphael Michel
aaf1b7776e Set up flag for japanese fields 2025-01-07 16:09:28 +01:00
Raphael Michel
d545b15d0d Fix incorrect language code for Japanese 2025-01-07 15:12:26 +01:00
Raphael Michel
0a334d1c67 Explicitly set none algorithm 2025-01-07 12:01:52 +01:00
dependabot[bot]
1a2fb688de Update pyjwt requirement from ==2.9.* to ==2.10.*
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.9.0...2.10.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-07 12:01:52 +01:00
Raphael Michel
c1333d6edb Add Japanese to supported languages 2025-01-07 11:37:42 +01:00
Hijiri Umemoto
e3e432a9e4 Translations: Update Japanese
Currently translated at 100.0% (5836 of 5836 strings)

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

powered by weblate
2025-01-07 11:19:37 +01:00
Hijiri Umemoto
36ea18970b Translations: Update Japanese
Currently translated at 100.0% (5836 of 5836 strings)

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

powered by weblate
2025-01-07 11:19:37 +01:00
Hector
bde2d50828 Translations: Update Spanish
Currently translated at 100.0% (5836 of 5836 strings)

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

powered by weblate
2025-01-07 11:19:37 +01:00
Hijiri Umemoto
e8334df908 Translations: Update Chinese (Traditional Han script)
Currently translated at 91.6% (5351 of 5836 strings)

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

powered by weblate
2025-01-07 11:19:37 +01:00
Hector
c8943785d7 Translations: Update Spanish
Currently translated at 100.0% (5836 of 5836 strings)

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

powered by weblate
2025-01-07 11:19:37 +01:00
Hijiri Umemoto
41b878b667 Translations: Update Turkish
Currently translated at 43.1% (2516 of 5836 strings)

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

powered by weblate
2025-01-07 11:19:37 +01:00
Hijiri Umemoto
4f63ba967b Translations: Update Chinese (Traditional Han script)
Currently translated at 91.3% (5331 of 5836 strings)

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

powered by weblate
2025-01-07 11:19:37 +01:00
12 changed files with 224 additions and 142 deletions

View File

@@ -72,7 +72,7 @@ dependencies = [
"packaging",
"paypalrestsdk==1.13.*",
"paypal-checkout-serversdk==1.0.*",
"PyJWT==2.9.*",
"PyJWT==2.10.*",
"phonenumberslite==8.13.*",
"Pillow==11.1.*",
"pretix-plugin-build",

View File

@@ -94,6 +94,7 @@ ALL_LANGUAGES = [
('el', _('Greek')),
('id', _('Indonesian')),
('it', _('Italian')),
('ja', _('Japanese')),
('lv', _('Latvian')),
('nb-no', _('Norwegian Bokmål')),
('pl', _('Polish')),

View File

@@ -619,7 +619,7 @@ class QuotaViewSet(ConditionalListView, viewsets.ModelViewSet):
def availability(self, request, *args, **kwargs):
quota = self.get_object()
qa = QuotaAvailability()
qa = QuotaAvailability(full_results=True)
qa.queue(quota)
qa.compute()
avail = qa.results[quota]

View File

@@ -62,6 +62,63 @@ from pretix.presale.style import get_fonts
logger = logging.getLogger(__name__)
def addon_aware_groupby(iterable, key, is_addon):
"""
We use groupby() to visually group identical lines on an invoice. For example, instead of
Product 1 5.00 EUR
Product 1 5.00 EUR
Product 1 5.00 EUR
Product 2 7.00 EUR
We want to print
3x Product 1 5.00 EUR = 15.00 EUR
Product 2 7.00 EUR
However, this fails for setups with addon-products since groupby() only groups consecutive
lines with the same identity. So in
Product 1 5.00 EUR
+ Addon 1 2.00 EUR
Product 1 5.00 EUR
+ Addon 1 2.00 EUR
Product 1 5.00 EUR
+ Addon 2 3.00 EUR
There is no consecutive repetition of the same entity. This function provides a specialised groupby which
understands the product/addon relationship and packs groups of these addons together if they are, in fact,
identical groups:
2x Product 1 5.00 EUR = 10.00 EUR
+ 2x Addon 1 2.00 EUR = 4.00 EUR
Product 1 5.00 EUR
+ Addon 2 3.00 EUR
"""
packed_groups = []
for i in iterable:
if is_addon(i):
packed_groups[-1][1].append(i)
else:
packed_groups.append((i, []))
# Each packed_groups element contains (parent product, list of addon products)
def _reorder(packed_groups):
# Emit the products as individual products again, reordered by "all parent products, then all addon products"
# within each group.
for group_grouper, grouped in groupby(packed_groups, key=lambda g: key(g[0]) + tuple(key(a) for a in g[1])):
grouped = list(grouped)
for grp in grouped:
yield grp[0]
for i in range(max(len(grp[1]) for grp in grouped)):
for grp in grouped:
if len(grp[1]) > i:
yield grp[1][i]
return groupby(_reorder(packed_groups), key)
class NumberedCanvas(Canvas):
def __init__(self, *args, **kwargs):
self.font_regular = kwargs.pop('font_regular')
@@ -635,7 +692,11 @@ class ClassicInvoiceRenderer(BaseReportlabInvoiceRenderer):
line.event_date_from, line.event_date_to)
total = Decimal('0.00')
for (description, tax_rate, tax_name, net_value, gross_value, *ignored), lines in groupby(self.invoice.lines.all(), key=_group_key):
for (description, tax_rate, tax_name, net_value, gross_value, *ignored), lines in addon_aware_groupby(
self.invoice.lines.all(),
key=_group_key,
is_addon=lambda l: l.description.startswith(" +"),
):
lines = list(lines)
if has_taxes:
if len(lines) > 1:

View File

@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-12-16 14:20+0000\n"
"PO-Revision-Date: 2025-01-03 14:22+0000\n"
"PO-Revision-Date: 2025-01-04 19:00+0000\n"
"Last-Translator: Hector <hector@demandaeventos.es>\n"
"Language-Team: Spanish <https://translate.pretix.eu/projects/pretix/pretix/"
"es/>\n"
@@ -500,19 +500,19 @@ msgstr "Pago confirmado"
#: pretix/api/webhooks.py:305
msgid "Order approved"
msgstr "Perdido aprobado"
msgstr "Pedido aprobado"
#: pretix/api/webhooks.py:309
msgid "Order denied"
msgstr "Perdido denegado"
msgstr "Pedido denegado"
#: pretix/api/webhooks.py:313
msgid "Order deleted"
msgstr "Perdido borrado"
msgstr "Pedido eliminado"
#: pretix/api/webhooks.py:317
msgid "Ticket checked in"
msgstr "Entrada comprobada"
msgstr "Entrada escaneada"
#: pretix/api/webhooks.py:321
msgid "Ticket check-in reverted"
@@ -533,7 +533,7 @@ msgstr "Evento eliminado"
#: pretix/api/webhooks.py:337
msgctxt "subevent"
msgid "Event series date added"
msgstr "Fecha de inicio de la serie de eventos creada"
msgstr "Fechas de la serie de eventos añadidas"
#: pretix/api/webhooks.py:341
msgctxt "subevent"
@@ -571,15 +571,15 @@ msgstr "Modo de pruebas de la tienda ha sido desactivado"
#: pretix/api/webhooks.py:370
msgid "Waiting list entry added"
msgstr "Agregado a la lista de espera"
msgstr "Elemento agregado a la lista de espera"
#: pretix/api/webhooks.py:374
msgid "Waiting list entry changed"
msgstr "Entrada a la lista de espera"
msgstr "Elemento de la lista de espera cambiado"
#: pretix/api/webhooks.py:378
msgid "Waiting list entry deleted"
msgstr "Entrada a la lista de espera eliminada"
msgstr "Elemento de la lista de espera eliminado"
#: pretix/api/webhooks.py:382
msgid "Waiting list entry received voucher"
@@ -612,11 +612,11 @@ msgstr "Este campo es obligatorio."
#: pretix/base/addressvalidation.py:213
msgid "Enter a postal code in the format XXX."
msgstr "Ingresa el código postal en el formato XXX."
msgstr "Ingresa el código postal en el formato XXXXX."
#: pretix/base/addressvalidation.py:222 pretix/base/addressvalidation.py:224
msgid "Enter a postal code in the format XXXX."
msgstr "Ingresa un código postal en el formato XXX."
msgstr "Ingresa un código postal en el formato XXXXX."
#: pretix/base/auth.py:146
#, python-brace-format
@@ -657,7 +657,7 @@ msgstr "Contraseña"
#: pretix/base/auth.py:176 pretix/base/auth.py:183
msgid "Your password must contain both numeric and alphabetic characters."
msgstr "Su contraseña debe contener caracteres numéricos y alfabéticos."
msgstr "Su contraseña debe contener caracteres alfanuméricos."
#: pretix/base/auth.py:202 pretix/base/auth.py:212
#, python-format
@@ -689,7 +689,7 @@ msgstr ""
#: pretix/base/context.py:45
#, python-brace-format
msgid "powered by {name} based on <a {a_attr}>pretix</a>"
msgstr "hecho posible por {name} basado en <a {a_attr}>pretix</a>"
msgstr "desarrollado por {name} basado en <a {a_attr}>pretix</a>"
#: pretix/base/context.py:52
#, python-format
@@ -703,7 +703,7 @@ msgstr "Código fuente"
#: pretix/base/customersso/oidc.py:61
#, python-brace-format
msgid "Configuration option \"{name}\" is missing."
msgstr "La opción de configuración \"{name}\" no existe."
msgstr "La opción de configuración \"{name}\" falta."
#: pretix/base/customersso/oidc.py:69 pretix/base/customersso/oidc.py:74
#, python-brace-format
@@ -723,7 +723,7 @@ msgstr "Proveedor SSO incompatible: \"{error}\"."
#: pretix/base/customersso/oidc.py:111
#, python-brace-format
msgid "You are not requesting \"{scope}\"."
msgstr "No esta solicitando \"{scope}\"."
msgstr "No estas solicitando \"{scope}\"."
#: pretix/base/customersso/oidc.py:117
#, python-brace-format
@@ -731,8 +731,8 @@ msgid ""
"You are requesting scope \"{scope}\" but provider only supports these: "
"{scopes}."
msgstr ""
"Está solicitando el scope \"{scope}\", pero el proveedor solo admite estos: "
"{scopes}."
"Estás solicitando la funcionalidad \"{scope}\", pero el proveedor solo "
"admite estos: {scopes}."
#: pretix/base/customersso/oidc.py:127
#, python-brace-format
@@ -740,7 +740,7 @@ msgid ""
"You are requesting field \"{field}\" but provider only supports these: "
"{fields}."
msgstr ""
"Está solicitando el campo \"{field}\", pero el proveedor solo admite estos: "
"Estás solicitando el campo \"{field}\", pero el proveedor solo admite estos: "
"{fields}."
#: pretix/base/customersso/oidc.py:137
@@ -759,7 +759,7 @@ msgstr ""
#: pretix/presale/views/customer.py:862
#, python-brace-format
msgid "Login was not successful. Error message: \"{error}\"."
msgstr "El inicio de sesión no fue exitoso. Mensaje de error: \"{error}\"."
msgstr "El inicio de sesión no tuvo éxito. Mensaje de error: \"{error}\"."
#: pretix/base/customersso/oidc.py:236
msgid ""
@@ -810,7 +810,7 @@ msgstr "Excel combinado (.xlsx)"
#: pretix/base/exporters/answers.py:54
msgid "Question answer file uploads"
msgstr "Cargas de archivos de respuestas a preguntas"
msgstr "Subida de archivo de preguntas y respuestas"
#: pretix/base/exporters/answers.py:55 pretix/base/exporters/json.py:52
#: pretix/base/exporters/mail.py:53 pretix/base/exporters/orderlist.py:87
@@ -893,12 +893,12 @@ msgstr "Todas las fechas"
#: pretix/base/exporters/customers.py:49 pretix/control/navigation.py:606
#: pretix/control/templates/pretixcontrol/organizers/edit.html:132
msgid "Customer accounts"
msgstr "Cuenta de cliente"
msgstr "Cuentas de clientes"
#: pretix/base/exporters/customers.py:51
msgctxt "export_category"
msgid "Customer accounts"
msgstr "Cuenta de cliente"
msgstr "Cuentas de clientes"
#: pretix/base/exporters/customers.py:52
msgid "Download a spreadsheet of all currently registered customer accounts."
@@ -912,7 +912,7 @@ msgstr ""
#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:36
#: pretix/presale/templates/pretixpresale/organizers/customer_base.html:37
msgid "Customer ID"
msgstr "ID Cliente"
msgstr "ID de cliente"
#: pretix/base/exporters/customers.py:65
#: pretix/control/templates/pretixcontrol/organizers/customer.html:32
@@ -1109,7 +1109,7 @@ msgstr ""
#: pretix/base/exporters/dekodi.py:105
#, python-brace-format
msgid "Event ticket {event}-{code}"
msgstr "Entrada para evento {event}-{code}"
msgstr "Entrada para el evento {event}-{code}"
#: pretix/base/exporters/dekodi.py:234 pretix/base/exporters/invoices.py:74
#: pretix/base/exporters/orderlist.py:128
@@ -1204,12 +1204,12 @@ msgstr "Hora de admisión"
#: pretix/base/exporters/events.py:65 pretix/base/models/event.py:598
#: pretix/base/models/event.py:1484 pretix/control/forms/subevents.py:93
msgid "Start of presale"
msgstr "Inicio de preventa"
msgstr "Inicio de la preventa"
#: pretix/base/exporters/events.py:66 pretix/base/models/event.py:592
#: pretix/base/models/event.py:1478 pretix/control/forms/subevents.py:99
msgid "End of presale"
msgstr "Finalización de preventa"
msgstr "Finalización de la preventa"
#: pretix/base/exporters/events.py:67 pretix/base/exporters/invoices.py:351
#: pretix/base/models/event.py:604 pretix/base/models/event.py:1490
@@ -1219,7 +1219,7 @@ msgstr "Ubicación"
#: pretix/base/exporters/events.py:68 pretix/base/models/event.py:607
#: pretix/base/models/event.py:1493
msgid "Latitude"
msgstr "Lalitud"
msgstr "Latitud"
#: pretix/base/exporters/events.py:69 pretix/base/models/event.py:615
#: pretix/base/models/event.py:1501
@@ -1246,7 +1246,7 @@ msgstr "Comentario interno"
#: pretix/control/templates/pretixcontrol/orders/refunds.html:50
#: pretix/control/templates/pretixcontrol/search/payments.html:93
msgid "Payment provider"
msgstr "Proveedor de pagos"
msgstr "Proveedor de pago"
#: pretix/base/exporters/invoices.py:84 pretix/base/exporters/invoices.py:86
#: pretix/control/forms/filter.py:206 pretix/control/forms/filter.py:1020
@@ -1272,7 +1272,7 @@ msgstr "Todas las facturas"
#: pretix/base/exporters/invoices.py:127
msgid "Download all invoices created by the system as a ZIP file of PDF files."
msgstr ""
"Descargue todas las facturas creadas por el sistema como un archivo ZIP de "
"Descargue todas las facturas creadas por el sistema en un archivo ZIP de "
"archivos PDF."
#: pretix/base/exporters/invoices.py:178
@@ -1446,7 +1446,7 @@ msgstr "País"
#: pretix/base/exporters/invoices.py:211 pretix/base/exporters/invoices.py:337
msgid "Tax ID"
msgstr "IVA-ID"
msgstr "CIF"
#: pretix/base/exporters/invoices.py:212 pretix/base/exporters/invoices.py:220
#: pretix/base/exporters/invoices.py:338 pretix/base/exporters/invoices.py:346
@@ -1490,7 +1490,7 @@ msgstr "Destinatario de la factura:"
#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:83
#: pretix/presale/templates/pretixpresale/event/order.html:307
msgid "Company"
msgstr "Compañía"
msgstr "Empresa"
#: pretix/base/exporters/invoices.py:215 pretix/base/exporters/invoices.py:341
msgid "Street address"
@@ -4567,13 +4567,13 @@ msgstr "Transacción manual"
#, python-format
msgctxt "invoice"
msgid "Tax ID: %s"
msgstr "IVA-ID: %s"
msgstr "CIF: %s"
#: pretix/base/models/invoices.py:191 pretix/base/services/invoices.py:139
#, python-format
msgctxt "invoice"
msgid "VAT-ID: %s"
msgstr "IVA-ID: %s"
msgstr "CIF: %s"
#: pretix/base/models/items.py:93
msgid "Category name"

View File

@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-12-16 14:20+0000\n"
"PO-Revision-Date: 2025-01-02 07:00+0000\n"
"PO-Revision-Date: 2025-01-06 00:00+0000\n"
"Last-Translator: Hijiri Umemoto <hijiri@umemoto.org>\n"
"Language-Team: Japanese <https://translate.pretix.eu/projects/pretix/pretix/"
"ja/>\n"
@@ -4552,7 +4552,7 @@ msgstr "アドオンカテゴリ"
#: pretix/base/models/items.py:222 pretix/base/models/items.py:278
msgid "Disable product for this date"
msgstr "この日付の製品を無効にしてください"
msgstr "この日付の製品を無効にする"
#: pretix/base/models/items.py:226 pretix/base/models/items.py:282
#: pretix/base/models/items.py:560
@@ -5638,7 +5638,7 @@ msgstr "支払い済みの注文"
#: pretix/base/models/orders.py:418
msgid "canceled (paid fee)"
msgstr "キャンセル(料金支払い済み)"
msgstr "キャンセル済み(支払い済み手数料"
#: pretix/base/models/orders.py:1031
msgid ""
@@ -6587,7 +6587,7 @@ msgstr "購入した製品"
#: pretix/base/services/placeholders.py:393
#: pretix/base/templates/pretixbase/email/order_details.html:147
msgid "View order details"
msgstr "注文の詳細を表示します"
msgstr "注文の詳細を表示す"
#: pretix/base/notifications.py:234
#, python-brace-format
@@ -6655,7 +6655,7 @@ msgstr "払い戻しをリクエストしました"
#: pretix/base/notifications.py:300
#, python-brace-format
msgid "You have been requested to issue a refund for {order.code}."
msgstr "{order.code}の返金手続きを依頼されました。"
msgstr "{order.code}の返金手続きがリクエストされました。"
#: pretix/base/payment.py:86
msgctxt "payment"
@@ -11831,7 +11831,7 @@ msgstr "ここをクリックして、通知設定を表示および変更"
#: pretix/base/templates/pretixbase/email/notification.html:60
msgid "Click here disable all notifications immediately."
msgstr "ここをクリックしてすぐにすべての通知を無効にしてください。"
msgstr "ここをクリックしてすべての通知を直ちに無効にする。"
#: pretix/base/templates/pretixbase/email/notification.txt:15
msgid "Click here to view and change your notification settings:"
@@ -20196,7 +20196,7 @@ msgstr "<strong>plus</strong> %(rate)s%% %(taxname)s"
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:409
#, python-format
msgid "incl. %(rate)s%% %(taxname)s"
msgstr "%(rate)s%% %(taxname)sを含む"
msgstr "%(taxname)s%(rate)s を含む"
#: pretix/control/templates/pretixcontrol/items/question.html:6
#: pretix/control/templates/pretixcontrol/items/question.html:9
@@ -31343,7 +31343,7 @@ msgstr "<strong>plus</strong> %(rate)s%% %(name)s"
#: pretix/presale/templates/pretixpresale/event/voucher.html:366
#, python-format
msgid "incl. %(rate)s%% %(name)s"
msgstr "%(rate)s%% %(name)s を含む"
msgstr "%(name)s %(rate)sを含む"
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:200
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:207
@@ -31564,7 +31564,7 @@ msgstr[0] "%(num)s 個の製品"
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:465
#, python-format
msgid "incl. %(tax_sum)s taxes"
msgstr "incl. %(tax_sum)s 税金"
msgstr "%(tax_sum)sを含む"
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:482
#, python-format
@@ -31594,7 +31594,7 @@ msgstr "チェックアウトを続行します"
#: pretix/presale/templates/pretixpresale/event/fragment_cart_box.html:63
msgid "Empty cart"
msgstr "空のカート"
msgstr "カートを空にする"
#: pretix/presale/templates/pretixpresale/event/fragment_cart_box.html:68
#: pretix/presale/templates/pretixpresale/event/index.html:236
@@ -31876,7 +31876,7 @@ msgstr "%(item)sのフルサイズの画像を表示"
#: pretix/presale/templates/pretixpresale/event/voucher.html:359
#, python-format
msgid "%(value)s incl. taxes"
msgstr "%(value)s 税込"
msgstr "税込%(value)s"
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:197
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:350
@@ -32242,7 +32242,7 @@ msgstr "注文された商品を変更します"
#: pretix/presale/templates/pretixpresale/event/order.html:290
#: pretix/presale/templates/pretixpresale/event/position.html:34
msgid "Change details"
msgstr "変更の詳細"
msgstr "詳細を変更"
#: pretix/presale/templates/pretixpresale/event/order.html:262
msgid ""

View File

@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-12-16 14:20+0000\n"
"PO-Revision-Date: 2024-12-30 22:00+0000\n"
"PO-Revision-Date: 2025-01-04 01:00+0000\n"
"Last-Translator: Hijiri Umemoto <hijiri@umemoto.org>\n"
"Language-Team: Turkish <https://translate.pretix.eu/projects/pretix/pretix/"
"tr/>\n"
@@ -1041,10 +1041,8 @@ msgid "Name"
msgstr "Ad"
#: pretix/base/exporters/customers.py:77 pretix/base/models/customers.py:99
#, fuzzy
#| msgid "This account is inactive."
msgid "Account active"
msgstr "Bu hesap aktif değildir."
msgstr "Hesap aktif"
#: pretix/base/exporters/customers.py:78 pretix/base/models/customers.py:100
#, fuzzy

View File

@@ -8,16 +8,16 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-12-16 14:20+0000\n"
"PO-Revision-Date: 2024-01-22 17:08+0000\n"
"Last-Translator: Raphael Michel <michel@rami.io>\n"
"Language-Team: Chinese (Traditional) <https://translate.pretix.eu/projects/"
"pretix/pretix/zh_Hant/>\n"
"PO-Revision-Date: 2025-01-04 19:00+0000\n"
"Last-Translator: Hijiri Umemoto <hijiri@umemoto.org>\n"
"Language-Team: Chinese (Traditional Han script) <https://translate.pretix.eu/"
"projects/pretix/pretix/zh_Hant/>\n"
"Language: zh_Hant\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Weblate 5.3.1\n"
"X-Generator: Weblate 5.9.2\n"
#: pretix/_base_settings.py:79
msgid "English"
@@ -37,11 +37,11 @@ msgstr "阿拉伯語"
#: pretix/_base_settings.py:83
msgid "Basque"
msgstr ""
msgstr "巴斯克語"
#: pretix/_base_settings.py:84
msgid "Catalan"
msgstr ""
msgstr "嘉泰羅尼亞語"
#: pretix/_base_settings.py:85
msgid "Chinese (simplified)"
@@ -85,7 +85,7 @@ msgstr "希臘語"
#: pretix/_base_settings.py:95
msgid "Indonesian"
msgstr ""
msgstr "印尼語"
#: pretix/_base_settings.py:96
msgid "Italian"
@@ -97,7 +97,7 @@ msgstr "拉脫維亞語"
#: pretix/_base_settings.py:98
msgid "Norwegian Bokmål"
msgstr ""
msgstr "挪威博克馬爾語"
#: pretix/_base_settings.py:99
msgid "Polish"
@@ -121,11 +121,11 @@ msgstr "俄語"
#: pretix/_base_settings.py:104
msgid "Slovak"
msgstr ""
msgstr "斯洛伐克語"
#: pretix/_base_settings.py:105
msgid "Swedish"
msgstr ""
msgstr "瑞典語"
#: pretix/_base_settings.py:106
msgid "Spanish"
@@ -582,10 +582,8 @@ msgid "Customer account changed"
msgstr "客戶帳戶電子郵件更改"
#: pretix/api/webhooks.py:394
#, fuzzy
#| msgid "The customer account has been anonymized."
msgid "Customer account anonymized"
msgstr "客戶帳戶已匿名化"
msgstr "客戶帳戶已匿名化"
#: pretix/base/addressvalidation.py:100 pretix/base/addressvalidation.py:103
#: pretix/base/addressvalidation.py:108 pretix/base/forms/questions.py:960
@@ -647,7 +645,7 @@ msgstr "密碼"
#: pretix/base/auth.py:176 pretix/base/auth.py:183
msgid "Your password must contain both numeric and alphabetic characters."
msgstr ""
msgstr "您的密碼必須包含數字和字母字元。"
#: pretix/base/auth.py:202 pretix/base/auth.py:212
#, python-format
@@ -655,7 +653,7 @@ msgid "Your password may not be the same as your previous password."
msgid_plural ""
"Your password may not be the same as one of your %(history_length)s previous "
"passwords."
msgstr[0] ""
msgstr[0] "您的密碼可能與您之前的 %(history_length)s密碼之一不同。"
#: pretix/base/channels.py:168
msgid "Online shop"
@@ -663,13 +661,13 @@ msgstr "網上商店"
#: pretix/base/channels.py:174
msgid "API"
msgstr ""
msgstr "API"
#: pretix/base/channels.py:175
msgid ""
"API sales channels come with no built-in functionality, but may be used for "
"custom integrations."
msgstr ""
msgstr "API銷售渠道沒有內建功能但可用於自定義整合。"
#: pretix/base/context.py:45
#, python-brace-format
@@ -2889,7 +2887,7 @@ msgstr "優惠券代碼"
#: pretix/base/forms/__init__.py:118
#, python-brace-format
msgid "You can use {markup_name} in this field."
msgstr ""
msgstr "您可以在此欄位中使用{markup_name}。"
#: pretix/base/forms/__init__.py:178
#, python-format
@@ -3089,6 +3087,8 @@ msgid ""
"up. Please note: to use literal \"{\" or \"}\", you need to double them as "
"\"{{\" and \"}}\"."
msgstr ""
"您的佔位符語法有誤。 請檢查佔位符上的開頭“{”和結尾“}”花括號是否匹配。 "
"請注意:要使用字面“{”或“}”,您需要將它們加倍為“{{”和“}}”。"
#: pretix/base/forms/validators.py:72 pretix/control/views/event.py:758
#, fuzzy, python-format
@@ -3097,10 +3097,9 @@ msgid "Invalid placeholder: {%(value)s}"
msgstr "無效的佔位元: %(value)ss"
#: pretix/base/forms/widgets.py:68
#, fuzzy, python-format
#| msgid "Sample city"
#, python-format
msgid "Sample: %s"
msgstr "範例城市"
msgstr "範例: %s"
#: pretix/base/forms/widgets.py:71
#, python-brace-format
@@ -3339,7 +3338,7 @@ msgstr ""
#: pretix/base/invoice.py:858
msgid "Default invoice renderer (European-style letter)"
msgstr ""
msgstr "預設發票渲染器(歐式信件)"
#: pretix/base/invoice.py:947
msgctxt "invoice"
@@ -3348,14 +3347,13 @@ msgstr "(請隨時報價)"
#: pretix/base/invoice.py:994
msgid "Simplified invoice renderer"
msgstr ""
msgstr "簡化的發票渲染器"
#: pretix/base/invoice.py:1013
#, fuzzy, python-brace-format
#| msgid "Event date range"
#, python-brace-format
msgctxt "invoice"
msgid "Event date: {date_range}"
msgstr "活動日期區間"
msgstr "活動日期: {date_range}"
#: pretix/base/media.py:71
msgid "Barcode / QR-Code"
@@ -3576,10 +3574,8 @@ msgid "Maximum usages"
msgstr "最大使用量"
#: pretix/base/modelimport_vouchers.py:79
#, fuzzy
#| msgid "Maximum number of items per order"
msgid "The maximum number of usages must be set."
msgstr "每項訂單的最大商品數量"
msgstr "必須設定最大使用次數。"
#: pretix/base/modelimport_vouchers.py:88 pretix/base/models/vouchers.py:205
msgid "Minimum usages"
@@ -3614,7 +3610,7 @@ msgstr "優惠券價值"
#: pretix/base/modelimport_vouchers.py:165
msgid "It is pointless to set a value without a price mode."
msgstr ""
msgstr "在沒有價格模式的情況下設定值是沒有意義的。"
#: pretix/base/modelimport_vouchers.py:237 pretix/base/models/items.py:2081
#: pretix/base/models/vouchers.py:272
@@ -3743,18 +3739,18 @@ msgstr ""
#: pretix/base/models/checkin.py:65
msgctxt "checkin"
msgid "Ignore check-ins on this list in statistics"
msgstr ""
msgstr "忽略統計中此列表中的簽到"
#: pretix/base/models/checkin.py:69
msgctxt "checkin"
msgid "Tickets with a check-in on this list should be considered \"used\""
msgstr ""
msgstr "此列表中有簽到的門票應被視為「已使用」"
#: pretix/base/models/checkin.py:70
msgid ""
"This is relevant in various situations, e.g. for deciding if a ticket can "
"still be canceled by the customer."
msgstr ""
msgstr "這與各種情況有關,例如用於決定客戶是否仍然可以取消門票。"
#: pretix/base/models/checkin.py:74
msgctxt "checkin"
@@ -4065,7 +4061,8 @@ msgid ""
"By default, the discount is applied across the same selection of products "
"than the condition for the discount given above. If you want, you can "
"however also select a different selection of products."
msgstr ""
msgstr "預設情況下,折扣適用於與上述折扣條件相同的產品選擇。 "
"然而,如果您願意,您也可以選擇不同的產品。"
#: pretix/base/models/discount.py:138
#, fuzzy
@@ -4356,7 +4353,7 @@ msgstr "對客戶顯示簽到次數"
msgid ""
"This field will be shown to filter events in the public event list and "
"calendar."
msgstr ""
msgstr "將顯示此欄位,以過濾公共活動列表和日曆中的活動。"
#: pretix/base/models/event.py:1731 pretix/control/forms/organizer.py:269
#: pretix/control/forms/organizer.py:273
@@ -5899,10 +5896,8 @@ msgid "Team members"
msgstr "團隊成員"
#: pretix/base/models/organizer.py:289
#, fuzzy
#| msgid "Do you really want to disable two-factor authentication?"
msgid "Require all members of this team to use two-factor authentication"
msgstr "你真的要禁用兩步驟驗證嗎?"
msgstr "要求該團隊的所有成員使用雙因素身份驗證"
#: pretix/base/models/organizer.py:290
msgid ""
@@ -7822,10 +7817,9 @@ msgid "number of entries before {datetime}"
msgstr "今日條目數數量"
#: pretix/base/services/checkin.py:320
#, fuzzy, python-brace-format
#| msgid "number of entries today"
#, python-brace-format
msgid "number of days with an entry since {datetime}"
msgstr "今日條目數數量"
msgstr "自 {datetime}以來條目的天數"
#: pretix/base/services/checkin.py:321
#, fuzzy, python-brace-format
@@ -13807,10 +13801,8 @@ msgstr ""
"的所有部分VIP區除外。"
#: pretix/control/forms/item.py:664
#, fuzzy
#| msgid "The ordered product \"{item}\" is no longer available."
msgid "Show product with info on why its unavailable"
msgstr "訂購的產品“{item}”不再可用"
msgstr "顯示產品,並瞭解為什麼它不可用"
#: pretix/control/forms/item.py:677
msgid ""
@@ -18881,10 +18873,8 @@ msgid "Calculation"
msgstr "取消"
#: pretix/control/templates/pretixcontrol/event/tax_edit.html:64
#, fuzzy
#| msgid "Reason:"
msgid "Reason"
msgstr "理由"
msgstr "理由"
#: pretix/control/templates/pretixcontrol/event/tax_edit.html:137
#: pretix/control/templates/pretixcontrol/subevents/bulk.html:251
@@ -19956,11 +19946,8 @@ msgid ""
msgstr "目前不可用,因為已設定此產品的有限時間範圍"
#: pretix/control/templates/pretixcontrol/items/discounts.html:111
#, fuzzy
#| msgctxt "discount"
#| msgid "Condition"
msgid "Condition:"
msgstr "條件"
msgstr "條件:"
#: pretix/control/templates/pretixcontrol/items/discounts.html:126
msgid "Applies to:"
@@ -22022,10 +22009,8 @@ msgid "Channel type"
msgstr "掃描"
#: pretix/control/templates/pretixcontrol/organizers/channel_delete.html:5
#, fuzzy
#| msgid "Sales channel"
msgid "Delete sales channel:"
msgstr "銷售管道"
msgstr "銷售管道:"
#: pretix/control/templates/pretixcontrol/organizers/channel_delete.html:10
#, fuzzy
@@ -22044,10 +22029,8 @@ msgid ""
msgstr "無法刪除此成員資格,因為它已在訂單中使用。將其結束日期更改為過去。"
#: pretix/control/templates/pretixcontrol/organizers/channel_edit.html:6
#, fuzzy
#| msgid "Sales channel"
msgid "Sales channel:"
msgstr "銷售管道"
msgstr "銷售管道:"
#: pretix/control/templates/pretixcontrol/organizers/channels.html:8
msgid ""
@@ -26454,10 +26437,8 @@ msgid "Login from new source detected"
msgstr "未檢測到訂購號"
#: pretix/helpers/security.py:170
#, fuzzy
#| msgid "Unknown country code."
msgid "Unknown country"
msgstr "未知國家代碼."
msgstr "未知國家"
#: pretix/multidomain/models.py:36
#, fuzzy
@@ -29485,7 +29466,7 @@ msgstr ""
#: pretix/plugins/stripe/payment.py:350 pretix/plugins/stripe/payment.py:1552
msgid "Alipay"
msgstr "Alipay"
msgstr "支付寶"
#: pretix/plugins/stripe/payment.py:358 pretix/plugins/stripe/payment.py:1564
msgid "Bancontact"
@@ -30070,16 +30051,12 @@ msgid "Enter the entity number, reference number, and amount."
msgstr ""
#: pretix/plugins/stripe/templates/pretixplugins/stripe/pending.html:25
#, fuzzy
#| msgid "Invoice number"
msgid "Entity number:"
msgstr "發票編號"
msgstr "公司編號"
#: pretix/plugins/stripe/templates/pretixplugins/stripe/pending.html:26
#, fuzzy
#| msgid "Reference code"
msgid "Reference number:"
msgstr "參考代碼"
msgstr "參考代碼:"
#: pretix/plugins/stripe/templates/pretixplugins/stripe/pending.html:35
msgid ""
@@ -31156,10 +31133,9 @@ msgstr "新價格:"
#: pretix/presale/templates/pretixpresale/event/voucher.html:176
#: pretix/presale/templates/pretixpresale/event/voucher.html:329
#: pretix/presale/templates/pretixpresale/event/voucher.html:331
#, fuzzy, python-format
#| msgid "Modify price for %(item)s"
#, python-format
msgid "Modify price for %(item)s, at least %(price)s"
msgstr "修改%(item)s 的價格"
msgstr "修改%(item)s的價格,至少 %(price)s"
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:153
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:294
@@ -31263,16 +31239,12 @@ msgid "Enter a voucher code below to buy this product."
msgstr "在下面輸入優惠券代碼以購買此票。"
#: pretix/presale/templates/pretixpresale/event/fragment_availability.html:10
#, fuzzy
#| msgid "Not available"
msgid "Not available yet."
msgstr "無法使用"
msgstr "尚不可用。"
#: pretix/presale/templates/pretixpresale/event/fragment_availability.html:14
#, fuzzy
#| msgid "Not available"
msgid "Not available any more."
msgstr "無法使用"
msgstr "不再可用。"
#: pretix/presale/templates/pretixpresale/event/fragment_availability.html:19
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:85
@@ -32615,7 +32587,7 @@ msgid ""
" "
msgstr ""
"\n"
" from %(start_date)s\n"
" %(start_date)s\n"
" "
#: pretix/presale/templates/pretixpresale/fragment_calendar_nav.html:12
@@ -33132,10 +33104,8 @@ msgid "This feature is only available in test mode."
msgstr "此禮品卡只能在測試模式下使用。"
#: pretix/presale/views/event.py:985
#, fuzzy
#| msgid "This account is disabled."
msgid "Time machine disabled!"
msgstr "此帳戶已禁用"
msgstr "時間機器被禁用"
#: pretix/presale/views/order.py:368 pretix/presale/views/order.py:433
#: pretix/presale/views/order.py:514
@@ -33266,14 +33236,12 @@ msgid ""
msgstr "你不能將自己添加到候補名單中,因為該商品目前有貨。"
#: pretix/presale/views/waiting.py:180
#, fuzzy, python-brace-format
#| msgid ""
#| "We've added you to the waiting list. You will receive an email as soon as "
#| "this product gets available again."
#, python-brace-format
msgid ""
"We've added you to the waiting list. We will send an email to {email} as "
"soon as this product gets available again."
msgstr "我們已將你添加到候補名單一旦該產品再次,您將收到一封電子郵件。"
msgstr "我們已將您列入候補名單。 "
"一旦該產品再次上市,我們將立即向{email}傳送電子郵件。"
#: pretix/presale/views/waiting.py:208
msgid "We could not find you on our waiting list."

View File

@@ -289,7 +289,7 @@ def _render_nup(input_files: List[str], num_pages: int, output_file: BytesIO, op
pass
try:
badges_pdf = PdfReader(input_files.pop())
badges_pdf = PdfReader(input_files.pop(0))
offset = 0
for i, chunk_indices in enumerate(_chunks(range(num_pages), badges_per_page * max_nup_pages)):
chunk = []
@@ -298,7 +298,7 @@ def _render_nup(input_files: List[str], num_pages: int, output_file: BytesIO, op
# file has beforehand
if j - offset >= len(badges_pdf.pages):
offset += len(badges_pdf.pages)
badges_pdf = PdfReader(input_files.pop())
badges_pdf = PdfReader(input_files.pop(0))
chunk.append(badges_pdf.pages[j - offset])
# Reset some internal state from pypdf. This will make it a little slower, but will prevent us from
# running out of memory if we process a really large file.

View File

@@ -37,7 +37,7 @@ class PayPalEnvironment(VendorPayPalEnvironment):
'payer_id': self.merchant_id
},
key=None,
algorithm=None,
algorithm="none",
)
return ""

View File

@@ -169,7 +169,7 @@ pre[lang=is], input[lang=is], textarea[lang=is], div[lang=is] { background-image
pre[lang=it], input[lang=it], textarea[lang=it], div[lang=it] { background-image: url(static('pretixbase/img/flags/it.png')); }
pre[lang=jm], input[lang=jm], textarea[lang=jm], div[lang=jm] { background-image: url(static('pretixbase/img/flags/jm.png')); }
pre[lang=jo], input[lang=jo], textarea[lang=jo], div[lang=jo] { background-image: url(static('pretixbase/img/flags/jo.png')); }
pre[lang=jp], input[lang=jp], textarea[lang=jp], div[lang=jp] { background-image: url(static('pretixbase/img/flags/jp.png')); }
pre[lang=ja], input[lang=ja], textarea[lang=ja], div[lang=ja] { background-image: url(static('pretixbase/img/flags/jp.png')); }
pre[lang=ke], input[lang=ke], textarea[lang=ke], div[lang=ke] { background-image: url(static('pretixbase/img/flags/ke.png')); }
pre[lang=kg], input[lang=kg], textarea[lang=kg], div[lang=kg] { background-image: url(static('pretixbase/img/flags/kg.png')); }
pre[lang=kh], input[lang=kh], textarea[lang=kh], div[lang=kh] { background-image: url(static('pretixbase/img/flags/kh.png')); }

View File

@@ -38,10 +38,12 @@ from decimal import Decimal
import pytest
from django.db import DatabaseError, transaction
from django.utils.itercompat import is_iterable
from django.utils.timezone import now
from django_countries.fields import Country
from django_scopes import scope, scopes_disabled
from pretix.base.invoice import addon_aware_groupby
from pretix.base.models import (
Event, ExchangeRate, Invoice, InvoiceAddress, Item, ItemVariation, Order,
OrderPosition, Organizer,
@@ -606,3 +608,55 @@ def test_sales_channels_qualify(env):
event.settings.set('invoice_generate_sales_channels', [])
assert invoice_qualified(order) is False
def test_addon_aware_groupby():
def is_addon(item):
is_addon, id, price = item
return is_addon
def key(item):
return item
def listify(it):
return [listify(i) if is_iterable(i) else i for i in it]
assert listify(addon_aware_groupby([
(False, 1, 5.00),
(False, 1, 5.00),
(False, 1, 5.00),
(False, 2, 7.00),
], key, is_addon)) == [
[[False, 1, 5.00], [
[False, 1, 5.00],
[False, 1, 5.00],
[False, 1, 5.00],
]],
[[False, 2, 7.00], [
[False, 2, 7.00],
]],
]
assert listify(addon_aware_groupby([
(False, 1, 5.00),
(True, 101, 2.00),
(False, 1, 5.00),
(True, 101, 2.00),
(False, 1, 5.00),
(True, 102, 3.00),
], key, is_addon)) == [
[[False, 1, 5.00], [
[False, 1, 5.00],
[False, 1, 5.00],
]],
[[True, 101, 2.00], [
[True, 101, 2.00],
[True, 101, 2.00],
]],
[[False, 1, 5.00], [
[False, 1, 5.00],
]],
[[True, 102, 3.00], [
[True, 102, 3.00],
]],
]