mirror of
https://github.com/pretix/pretix.git
synced 2026-02-17 08:32:28 +00:00
Compare commits
76 Commits
update-dja
...
mail-perf
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a883f709d0 | ||
|
|
f24429a7c5 | ||
|
|
29ed07ccce | ||
|
|
dd0cd7ab0b | ||
|
|
d7df906995 | ||
|
|
839f4b4657 | ||
|
|
74f7e1f61c | ||
|
|
47919afab0 | ||
|
|
819daa99f7 | ||
|
|
8512e79d68 | ||
|
|
52672ae25b | ||
|
|
ad752dc617 | ||
|
|
43c6c33bd8 | ||
|
|
88c9f8c047 | ||
|
|
2d2663f15f | ||
|
|
ae6014708b | ||
|
|
d1686df07c | ||
|
|
4d60d7bfbc | ||
|
|
c0b93fedc5 | ||
|
|
2eaa6c3069 | ||
|
|
db982c9ef4 | ||
|
|
f9f6ee94ae | ||
|
|
99c257d392 | ||
|
|
e2cb83ce28 | ||
|
|
d7b7d3cc5f | ||
|
|
721ac8a500 | ||
|
|
5796cfe03f | ||
|
|
63f1c4f793 | ||
|
|
47f409171d | ||
|
|
27fcdff17f | ||
|
|
a38a96f186 | ||
|
|
700ea77e39 | ||
|
|
06104ff483 | ||
|
|
fb5697a27b | ||
|
|
9a9ad6d6d1 | ||
|
|
a05845790e | ||
|
|
a0830dd033 | ||
|
|
dba2529f6b | ||
|
|
9c0ea8f179 | ||
|
|
1f0501a647 | ||
|
|
d2e6446238 | ||
|
|
d519fcfe0d | ||
|
|
c7226303be | ||
|
|
9406e941bc | ||
|
|
919e598f8a | ||
|
|
672692d578 | ||
|
|
9429dc7e91 | ||
|
|
5c8dbd99dd | ||
|
|
cfbb8310f0 | ||
|
|
d37d9a861c | ||
|
|
43a9cf29b2 | ||
|
|
047ad438a7 | ||
|
|
ec8d921fcf | ||
|
|
39e6ef4365 | ||
|
|
4d8b032591 | ||
|
|
e8193e408b | ||
|
|
6723d8c07c | ||
|
|
c30134f36c | ||
|
|
0617fc04ec | ||
|
|
e90b54280a | ||
|
|
39ea2889ba | ||
|
|
76230bd37b | ||
|
|
86b8c5e90f | ||
|
|
7a2027c61b | ||
|
|
55de5ef45b | ||
|
|
39e6954828 | ||
|
|
7849d98672 | ||
|
|
c325164059 | ||
|
|
8fc19c62dd | ||
|
|
20feaebbbd | ||
|
|
4587a9e630 | ||
|
|
9fe0e6eb67 | ||
|
|
bab7e54f35 | ||
|
|
352efa40e7 | ||
|
|
50da7d4261 | ||
|
|
53cc59d41d |
@@ -60,6 +60,9 @@ The following values for ``action_types`` are valid with pretix core:
|
||||
* ``pretix.event.added``
|
||||
* ``pretix.event.changed``
|
||||
* ``pretix.event.deleted``
|
||||
* ``pretix.giftcards.created``
|
||||
* ``pretix.giftcards.modified``
|
||||
* ``pretix.giftcards.transaction.*``
|
||||
* ``pretix.voucher.added``
|
||||
* ``pretix.voucher.changed``
|
||||
* ``pretix.voucher.deleted``
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
sphinx==9.1.*
|
||||
sphinx-rtd-theme~=3.1.0
|
||||
sphinxcontrib-httpdomain~=1.8.1
|
||||
sphinxcontrib-httpdomain~=2.0.0
|
||||
sphinxcontrib-images~=1.0.1
|
||||
sphinxcontrib-jquery~=4.1
|
||||
sphinxcontrib-spelling~=8.0.2
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
-e ../
|
||||
sphinx==9.1.*
|
||||
sphinx-rtd-theme~=3.1.0
|
||||
sphinxcontrib-httpdomain~=1.8.1
|
||||
sphinxcontrib-httpdomain~=2.0.0
|
||||
sphinxcontrib-images~=1.0.1
|
||||
sphinxcontrib-jquery~=4.1
|
||||
sphinxcontrib-spelling~=8.0.2
|
||||
|
||||
@@ -22,7 +22,7 @@ classifiers = [
|
||||
"Programming Language :: Python :: 3.9",
|
||||
"Programming Language :: Python :: 3.10",
|
||||
"Programming Language :: Python :: 3.11",
|
||||
"Framework :: Django :: 5.2",
|
||||
"Framework :: Django :: 4.2",
|
||||
]
|
||||
|
||||
dependencies = [
|
||||
@@ -33,10 +33,10 @@ dependencies = [
|
||||
"celery==5.6.*",
|
||||
"chardet==5.2.*",
|
||||
"cryptography>=44.0.0",
|
||||
"css-inline==0.19.*",
|
||||
"css-inline==0.20.*",
|
||||
"defusedcsv>=1.1.0",
|
||||
"dnspython==2.*",
|
||||
"Django[argon2]==5.2.*",
|
||||
"Django[argon2]==4.2.*,>=4.2.26",
|
||||
"django-bootstrap3==26.1",
|
||||
"django-compressor==4.6.0",
|
||||
"django-countries==8.2.*",
|
||||
@@ -65,7 +65,7 @@ dependencies = [
|
||||
"kombu==5.6.*",
|
||||
"libsass==0.23.*",
|
||||
"lxml",
|
||||
"markdown==3.10.1", # 3.3.5 requires importlib-metadata>=4.4, but django-bootstrap3 requires importlib-metadata<3.
|
||||
"markdown==3.10.2", # 3.3.5 requires importlib-metadata>=4.4, but django-bootstrap3 requires importlib-metadata<3.
|
||||
# We can upgrade markdown again once django-bootstrap3 upgrades or once we drop Python 3.6 and 3.7
|
||||
"mt-940==4.30.*",
|
||||
"oauthlib==3.3.*",
|
||||
@@ -73,7 +73,7 @@ dependencies = [
|
||||
"packaging",
|
||||
"paypalrestsdk==1.13.*",
|
||||
"paypal-checkout-serversdk==1.0.*",
|
||||
"PyJWT==2.10.*",
|
||||
"PyJWT==2.11.*",
|
||||
"phonenumberslite==9.0.*",
|
||||
"Pillow==12.1.*",
|
||||
"pretix-plugin-build",
|
||||
@@ -92,7 +92,7 @@ dependencies = [
|
||||
"redis==7.1.*",
|
||||
"reportlab==4.4.*",
|
||||
"requests==2.32.*",
|
||||
"sentry-sdk==2.51.*",
|
||||
"sentry-sdk==2.52.*",
|
||||
"sepaxml==2.7.*",
|
||||
"stripe==7.9.*",
|
||||
"text-unidecode==1.*",
|
||||
|
||||
@@ -249,12 +249,17 @@ class GiftCardViewSet(viewsets.ModelViewSet):
|
||||
def perform_create(self, serializer):
|
||||
value = serializer.validated_data.pop('value')
|
||||
inst = serializer.save(issuer=self.request.organizer)
|
||||
inst.transactions.create(value=value, acceptor=self.request.organizer)
|
||||
inst.log_action(
|
||||
'pretix.giftcards.transaction.manual',
|
||||
action='pretix.giftcards.created',
|
||||
user=self.request.user,
|
||||
auth=self.request.auth,
|
||||
data=merge_dicts(self.request.data, {'id': inst.pk})
|
||||
)
|
||||
inst.transactions.create(value=value, acceptor=self.request.organizer)
|
||||
inst.log_action(
|
||||
action='pretix.giftcards.transaction.manual',
|
||||
user=self.request.user,
|
||||
auth=self.request.auth,
|
||||
data=merge_dicts(self.request.data, {'id': inst.pk, 'acceptor_id': self.request.organizer.id})
|
||||
)
|
||||
|
||||
@transaction.atomic()
|
||||
@@ -269,7 +274,7 @@ class GiftCardViewSet(viewsets.ModelViewSet):
|
||||
inst = serializer.save(secret=serializer.instance.secret, currency=serializer.instance.currency,
|
||||
testmode=serializer.instance.testmode)
|
||||
inst.log_action(
|
||||
'pretix.giftcards.modified',
|
||||
action='pretix.giftcards.modified',
|
||||
user=self.request.user,
|
||||
auth=self.request.auth,
|
||||
data=self.request.data,
|
||||
@@ -282,10 +287,10 @@ class GiftCardViewSet(viewsets.ModelViewSet):
|
||||
diff = value - old_value
|
||||
inst.transactions.create(value=diff, acceptor=self.request.organizer)
|
||||
inst.log_action(
|
||||
'pretix.giftcards.transaction.manual',
|
||||
action='pretix.giftcards.transaction.manual',
|
||||
user=self.request.user,
|
||||
auth=self.request.auth,
|
||||
data={'value': diff}
|
||||
data={'value': diff, 'acceptor_id': self.request.organizer.id}
|
||||
)
|
||||
|
||||
return inst
|
||||
@@ -309,10 +314,14 @@ class GiftCardViewSet(viewsets.ModelViewSet):
|
||||
}, status=status.HTTP_409_CONFLICT)
|
||||
gc.transactions.create(value=value, text=text, info=info, acceptor=self.request.organizer)
|
||||
gc.log_action(
|
||||
'pretix.giftcards.transaction.manual',
|
||||
action='pretix.giftcards.transaction.manual',
|
||||
user=self.request.user,
|
||||
auth=self.request.auth,
|
||||
data={'value': value, 'text': text}
|
||||
data={
|
||||
'value': value,
|
||||
'text': text,
|
||||
'acceptor_id': self.request.organizer.id
|
||||
}
|
||||
)
|
||||
return Response(GiftCardSerializer(gc, context=self.get_serializer_context()).data, status=status.HTTP_200_OK)
|
||||
|
||||
|
||||
@@ -174,6 +174,35 @@ class ParametrizedEventWebhookEvent(ParametrizedWebhookEvent):
|
||||
}
|
||||
|
||||
|
||||
class ParametrizedGiftcardWebhookEvent(ParametrizedWebhookEvent):
|
||||
def build_payload(self, logentry: LogEntry):
|
||||
giftcard = logentry.content_object
|
||||
if not giftcard:
|
||||
return None
|
||||
|
||||
return {
|
||||
'notification_id': logentry.pk,
|
||||
'issuer_id': logentry.organizer_id,
|
||||
'giftcard': giftcard.pk,
|
||||
'action': logentry.action_type,
|
||||
}
|
||||
|
||||
|
||||
class ParametrizedGiftcardTransactionWebhookEvent(ParametrizedWebhookEvent):
|
||||
def build_payload(self, logentry: LogEntry):
|
||||
giftcard = logentry.content_object
|
||||
if not giftcard:
|
||||
return None
|
||||
|
||||
return {
|
||||
'notification_id': logentry.pk,
|
||||
'issuer_id': logentry.organizer_id,
|
||||
'acceptor_id': logentry.parsed_data.get('acceptor_id'),
|
||||
'giftcard': giftcard.pk,
|
||||
'action': logentry.action_type,
|
||||
}
|
||||
|
||||
|
||||
class ParametrizedVoucherWebhookEvent(ParametrizedWebhookEvent):
|
||||
|
||||
def build_payload(self, logentry: LogEntry):
|
||||
@@ -433,6 +462,18 @@ def register_default_webhook_events(sender, **kwargs):
|
||||
'pretix.customer.anonymized',
|
||||
_('Customer account anonymized'),
|
||||
),
|
||||
ParametrizedGiftcardWebhookEvent(
|
||||
'pretix.giftcards.created',
|
||||
_('Gift card added'),
|
||||
),
|
||||
ParametrizedGiftcardWebhookEvent(
|
||||
'pretix.giftcards.modified',
|
||||
_('Gift card modified'),
|
||||
),
|
||||
ParametrizedGiftcardTransactionWebhookEvent(
|
||||
'pretix.giftcards.transaction.*',
|
||||
_('Gift card used in transcation'),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ from pretix.base.templatetags.rich_text import (
|
||||
DEFAULT_CALLBACKS, EMAIL_RE, URL_RE, abslink_callback,
|
||||
markdown_compile_email, truelink_callback,
|
||||
)
|
||||
from pretix.helpers.format import SafeFormatter, format_map
|
||||
from pretix.helpers.format import FormattedString, SafeFormatter, format_map
|
||||
|
||||
from pretix.base.services.placeholders import ( # noqa
|
||||
get_available_placeholders, PlaceholderContext
|
||||
@@ -141,6 +141,7 @@ class TemplateBasedMailRenderer(BaseHTMLMailRenderer):
|
||||
return markdown_compile_email(plaintext, context=context)
|
||||
|
||||
def render(self, plain_body: str, plain_signature: str, subject: str, order, position, context) -> str:
|
||||
apply_format_map = not isinstance(plain_body, FormattedString)
|
||||
body_md = self.compile_markdown(plain_body, context)
|
||||
if context:
|
||||
linker = bleach.Linker(
|
||||
@@ -149,12 +150,13 @@ class TemplateBasedMailRenderer(BaseHTMLMailRenderer):
|
||||
callbacks=DEFAULT_CALLBACKS + [truelink_callback, abslink_callback],
|
||||
parse_email=True
|
||||
)
|
||||
body_md = format_map(
|
||||
body_md,
|
||||
context=context,
|
||||
mode=SafeFormatter.MODE_RICH_TO_HTML,
|
||||
linkifier=linker
|
||||
)
|
||||
if apply_format_map:
|
||||
body_md = format_map(
|
||||
body_md,
|
||||
context=context,
|
||||
mode=SafeFormatter.MODE_RICH_TO_HTML,
|
||||
linkifier=linker
|
||||
)
|
||||
htmlctx = {
|
||||
'site': settings.PRETIX_INSTANCE_NAME,
|
||||
'site_url': settings.SITE_URL,
|
||||
|
||||
@@ -890,18 +890,18 @@ class BaseQuestionsForm(forms.Form):
|
||||
if not help_text:
|
||||
if q.valid_date_min and q.valid_date_max:
|
||||
help_text = format_lazy(
|
||||
'Please enter a date between {min} and {max}.',
|
||||
_('Please enter a date between {min} and {max}.'),
|
||||
min=date_format(q.valid_date_min, "SHORT_DATE_FORMAT"),
|
||||
max=date_format(q.valid_date_max, "SHORT_DATE_FORMAT"),
|
||||
)
|
||||
elif q.valid_date_min:
|
||||
help_text = format_lazy(
|
||||
'Please enter a date no earlier than {min}.',
|
||||
_('Please enter a date no earlier than {min}.'),
|
||||
min=date_format(q.valid_date_min, "SHORT_DATE_FORMAT"),
|
||||
)
|
||||
elif q.valid_date_max:
|
||||
help_text = format_lazy(
|
||||
'Please enter a date no later than {max}.',
|
||||
_('Please enter a date no later than {max}.'),
|
||||
max=date_format(q.valid_date_max, "SHORT_DATE_FORMAT"),
|
||||
)
|
||||
if initial and initial.answer:
|
||||
@@ -939,18 +939,18 @@ class BaseQuestionsForm(forms.Form):
|
||||
if not help_text:
|
||||
if q.valid_datetime_min and q.valid_datetime_max:
|
||||
help_text = format_lazy(
|
||||
'Please enter a date and time between {min} and {max}.',
|
||||
_('Please enter a date and time between {min} and {max}.'),
|
||||
min=date_format(q.valid_datetime_min, "SHORT_DATETIME_FORMAT"),
|
||||
max=date_format(q.valid_datetime_max, "SHORT_DATETIME_FORMAT"),
|
||||
)
|
||||
elif q.valid_datetime_min:
|
||||
help_text = format_lazy(
|
||||
'Please enter a date and time no earlier than {min}.',
|
||||
_('Please enter a date and time no earlier than {min}.'),
|
||||
min=date_format(q.valid_datetime_min, "SHORT_DATETIME_FORMAT"),
|
||||
)
|
||||
elif q.valid_datetime_max:
|
||||
help_text = format_lazy(
|
||||
'Please enter a date and time no later than {max}.',
|
||||
_('Please enter a date and time no later than {max}.'),
|
||||
max=date_format(q.valid_datetime_max, "SHORT_DATETIME_FORMAT"),
|
||||
)
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#
|
||||
from typing import Optional
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django_countries.fields import Country
|
||||
|
||||
from pretix.base.models import Invoice, InvoiceAddress
|
||||
@@ -106,6 +107,22 @@ class TransmissionType:
|
||||
def transmission_info_to_form_data(self, transmission_info: dict) -> dict:
|
||||
return transmission_info
|
||||
|
||||
def describe_info(self, transmission_info: dict, country: Country, is_business: bool):
|
||||
form_data = self.transmission_info_to_form_data(transmission_info)
|
||||
data = []
|
||||
visible_field_keys = self.invoice_address_form_fields_visible(country, is_business)
|
||||
for k, f in self.invoice_address_form_fields.items():
|
||||
if k not in visible_field_keys:
|
||||
continue
|
||||
v = form_data.get(k)
|
||||
if v is True:
|
||||
v = _("Yes")
|
||||
elif v is False:
|
||||
v = _("No")
|
||||
if v:
|
||||
data.append((f.label, v))
|
||||
return data
|
||||
|
||||
def pdf_watermark(self) -> Optional[str]:
|
||||
"""
|
||||
Return a watermark that should be rendered across the PDF file.
|
||||
|
||||
@@ -36,9 +36,8 @@ from django.core.management.commands.makemigrations import Command as Parent
|
||||
|
||||
from ._migrations import monkeypatch_migrations
|
||||
|
||||
monkeypatch_migrations()
|
||||
|
||||
|
||||
class Command(Parent):
|
||||
|
||||
def handle(self, *args, **kwargs):
|
||||
monkeypatch_migrations()
|
||||
return super().handle(*args, **kwargs)
|
||||
pass
|
||||
|
||||
@@ -41,20 +41,16 @@ class Migration(migrations.Migration):
|
||||
name='datetime',
|
||||
field=models.DateTimeField(),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
'logentry',
|
||||
models.Index(fields=('datetime', 'id'), name="pretixbase__datetim_b1fe5a_idx"),
|
||||
migrations.AlterIndexTogether(
|
||||
name='logentry',
|
||||
index_together={('datetime', 'id')},
|
||||
),
|
||||
migrations.AddIndex(
|
||||
'order',
|
||||
models.Index(fields=["datetime", "id"], name="pretixbase__datetim_66aff0_idx"),
|
||||
migrations.AlterIndexTogether(
|
||||
name='order',
|
||||
index_together={('datetime', 'id'), ('last_modified', 'id')},
|
||||
),
|
||||
migrations.AddIndex(
|
||||
'order',
|
||||
models.Index(fields=["last_modified", "id"], name="pretixbase__last_mo_4ebf8b_idx"),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
'transaction',
|
||||
models.Index(fields=('datetime', 'id'), name="pretixbase__datetim_b20405_idx"),
|
||||
migrations.AlterIndexTogether(
|
||||
name='transaction',
|
||||
index_together={('datetime', 'id')},
|
||||
),
|
||||
]
|
||||
|
||||
@@ -61,10 +61,7 @@ class Migration(migrations.Migration):
|
||||
options={
|
||||
'ordering': ('identifier', 'type', 'organizer'),
|
||||
'unique_together': {('identifier', 'type', 'organizer')},
|
||||
'indexes': [
|
||||
models.Index(fields=('identifier', 'type', 'organizer'), name='reusable_medium_organizer_index'),
|
||||
models.Index(fields=('updated', 'id'), name="pretixbase__updated_093277_idx")
|
||||
],
|
||||
'index_together': {('identifier', 'type', 'organizer'), ('updated', 'id')},
|
||||
},
|
||||
bases=(models.Model, pretix.base.models.base.LoggingMixin),
|
||||
),
|
||||
|
||||
@@ -9,6 +9,31 @@ class Migration(migrations.Migration):
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameIndex(
|
||||
model_name="logentry",
|
||||
new_name="pretixbase__datetim_b1fe5a_idx",
|
||||
old_fields=("datetime", "id"),
|
||||
),
|
||||
migrations.RenameIndex(
|
||||
model_name="order",
|
||||
new_name="pretixbase__datetim_66aff0_idx",
|
||||
old_fields=("datetime", "id"),
|
||||
),
|
||||
migrations.RenameIndex(
|
||||
model_name="order",
|
||||
new_name="pretixbase__last_mo_4ebf8b_idx",
|
||||
old_fields=("last_modified", "id"),
|
||||
),
|
||||
migrations.RenameIndex(
|
||||
model_name="reusablemedium",
|
||||
new_name="pretixbase__updated_093277_idx",
|
||||
old_fields=("updated", "id"),
|
||||
),
|
||||
migrations.RenameIndex(
|
||||
model_name="transaction",
|
||||
new_name="pretixbase__datetim_b20405_idx",
|
||||
old_fields=("datetime", "id"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="attendeeprofile",
|
||||
name="id",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Generated by Django 4.2.10 on 2024-04-02 15:16
|
||||
|
||||
from django.db import migrations, models
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
@@ -10,8 +10,8 @@ class Migration(migrations.Migration):
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveIndex(
|
||||
"reusablemedium",
|
||||
'reusable_medium_organizer_index',
|
||||
migrations.AlterIndexTogether(
|
||||
name="reusablemedium",
|
||||
index_together=set(),
|
||||
),
|
||||
]
|
||||
|
||||
@@ -130,6 +130,8 @@ class LoggingMixin:
|
||||
organizer_id = self.event.organizer_id
|
||||
elif hasattr(self, 'organizer_id'):
|
||||
organizer_id = self.organizer_id
|
||||
elif hasattr(self, 'issuer_id'):
|
||||
organizer_id = self.issuer_id
|
||||
|
||||
if user and not user.is_authenticated:
|
||||
user = None
|
||||
|
||||
@@ -40,6 +40,7 @@ from i18nfield.fields import I18nCharField
|
||||
from phonenumber_field.modelfields import PhoneNumberField
|
||||
|
||||
from pretix.base.banlist import banned
|
||||
from pretix.base.i18n import language
|
||||
from pretix.base.models.base import LoggedModel
|
||||
from pretix.base.models.fields import MultiStringField
|
||||
from pretix.base.models.giftcards import GiftCardTransaction
|
||||
@@ -164,6 +165,28 @@ class Customer(LoggedModel):
|
||||
self.attendee_profiles.all().delete()
|
||||
self.invoice_addresses.all().delete()
|
||||
|
||||
def send_security_notice(self, message, email=None):
|
||||
from pretix.base.services.mail import SendMailException, mail
|
||||
from pretix.multidomain.urlreverse import build_absolute_uri
|
||||
|
||||
try:
|
||||
with language(self.locale):
|
||||
mail(
|
||||
email or self.email,
|
||||
self.organizer.settings.mail_subject_customer_security_notice,
|
||||
self.organizer.settings.mail_text_customer_security_notice,
|
||||
{
|
||||
**self.get_email_context(),
|
||||
'message': str(message),
|
||||
'url': build_absolute_uri(self.organizer, 'presale:organizer.customer.index')
|
||||
},
|
||||
customer=self,
|
||||
organizer=self.organizer,
|
||||
locale=self.locale
|
||||
)
|
||||
except SendMailException:
|
||||
pass # Already logged
|
||||
|
||||
@scopes_disabled()
|
||||
def assign_identifier(self):
|
||||
charset = list('ABCDEFGHJKLMNPQRSTUVWXYZ23456789')
|
||||
|
||||
@@ -88,7 +88,7 @@ class LogEntry(models.Model):
|
||||
|
||||
class Meta:
|
||||
ordering = ('-datetime', '-id')
|
||||
indexes = [models.Index(fields=["datetime", "id"], name="pretixbase__datetim_b1fe5a_idx")]
|
||||
indexes = [models.Index(fields=["datetime", "id"])]
|
||||
|
||||
def display(self):
|
||||
from pretix.base.logentrytype_registry import log_entry_types
|
||||
|
||||
@@ -122,7 +122,7 @@ class ReusableMedium(LoggedModel):
|
||||
class Meta:
|
||||
unique_together = (("identifier", "type", "organizer"),)
|
||||
indexes = [
|
||||
models.Index(fields=("updated", "id"), name="pretixbase__updated_093277_idx"),
|
||||
models.Index(fields=("updated", "id")),
|
||||
]
|
||||
ordering = "identifier", "type", "organizer"
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ from pretix.base.timemachine import time_machine_now
|
||||
|
||||
from ...helpers import OF_SELF
|
||||
from ...helpers.countries import CachedCountries, FastCountryField
|
||||
from ...helpers.format import format_map
|
||||
from ...helpers.format import FormattedString, format_map
|
||||
from ...helpers.names import build_name
|
||||
from ...testutils.middleware import debugflags_var
|
||||
from ._transactions import (
|
||||
@@ -337,8 +337,8 @@ class Order(LockModel, LoggedModel):
|
||||
verbose_name_plural = _("Orders")
|
||||
ordering = ("-datetime", "-pk")
|
||||
indexes = [
|
||||
models.Index(fields=["datetime", "id"], name="pretixbase__datetim_66aff0_idx"),
|
||||
models.Index(fields=["last_modified", "id"], name="pretixbase__last_mo_4ebf8b_idx"),
|
||||
models.Index(fields=["datetime", "id"]),
|
||||
models.Index(fields=["last_modified", "id"]),
|
||||
]
|
||||
constraints = [
|
||||
models.UniqueConstraint(fields=["organizer", "code"], name="order_organizer_code_uniq"),
|
||||
@@ -1178,7 +1178,8 @@ class Order(LockModel, LoggedModel):
|
||||
recipient = position.attendee_email
|
||||
|
||||
email_content = render_mail(template, context)
|
||||
subject = format_map(subject, context)
|
||||
if not isinstance(subject, FormattedString):
|
||||
subject = format_map(subject, context)
|
||||
mail(
|
||||
recipient, subject, template, context,
|
||||
self.event, self.locale, self, headers=headers, sender=sender,
|
||||
@@ -2907,7 +2908,8 @@ class OrderPosition(AbstractPosition):
|
||||
with language(self.order.locale, self.order.event.settings.region):
|
||||
recipient = self.attendee_email
|
||||
email_content = render_mail(template, context)
|
||||
subject = format_map(subject, context)
|
||||
if not isinstance(subject, FormattedString):
|
||||
subject = format_map(subject, context)
|
||||
mail(
|
||||
recipient, subject, template, context,
|
||||
self.event, self.order.locale, order=self.order, headers=headers, sender=sender,
|
||||
@@ -3102,7 +3104,7 @@ class Transaction(models.Model):
|
||||
class Meta:
|
||||
ordering = 'datetime', 'pk'
|
||||
indexes = [
|
||||
models.Index(fields=['datetime', 'id'], name="pretixbase__datetim_b20405_idx")
|
||||
models.Index(fields=['datetime', 'id'])
|
||||
]
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
@@ -3507,18 +3509,10 @@ class InvoiceAddress(models.Model):
|
||||
def describe_transmission(self):
|
||||
from pretix.base.invoicing.transmission import transmission_types
|
||||
data = []
|
||||
|
||||
t, __ = transmission_types.get(identifier=self.transmission_type)
|
||||
data.append((_("Transmission type"), t.public_name))
|
||||
form_data = t.transmission_info_to_form_data(self.transmission_info or {})
|
||||
for k, f in t.invoice_address_form_fields.items():
|
||||
v = form_data.get(k)
|
||||
if v is True:
|
||||
v = _("Yes")
|
||||
elif v is False:
|
||||
v = _("No")
|
||||
if v:
|
||||
data.append((f.label, v))
|
||||
if self.transmission_info:
|
||||
data += t.describe_info(self.transmission_info, self.country, self.is_business)
|
||||
return data
|
||||
|
||||
|
||||
|
||||
@@ -1646,6 +1646,13 @@ class GiftCardPayment(BasePaymentProvider):
|
||||
'transaction_id': trans.pk,
|
||||
}
|
||||
payment.confirm(send_mail=not is_early_special_case, generate_invoice=not is_early_special_case)
|
||||
gc.log_action(
|
||||
action='pretix.giftcards.transaction.payment',
|
||||
data={
|
||||
'value': trans.value,
|
||||
'acceptor_id': self.event.organizer.id
|
||||
}
|
||||
)
|
||||
except PaymentException as e:
|
||||
payment.fail(info={'error': str(e)})
|
||||
raise e
|
||||
@@ -1670,6 +1677,14 @@ class GiftCardPayment(BasePaymentProvider):
|
||||
'transaction_id': trans.pk,
|
||||
}
|
||||
refund.done()
|
||||
gc.log_action(
|
||||
action='pretix.giftcards.transaction.refund',
|
||||
data={
|
||||
'value': refund.amount,
|
||||
'acceptor_id': self.event.organizer.id,
|
||||
'text': refund.comment,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@receiver(register_payment_providers, dispatch_uid="payment_free")
|
||||
|
||||
@@ -65,7 +65,7 @@ def get_all_plugins(*, event=None, organizer=None) -> List[type]:
|
||||
if app.name in settings.PRETIX_PLUGINS_EXCLUDE:
|
||||
continue
|
||||
|
||||
level = getattr(app, "level", PLUGIN_LEVEL_EVENT)
|
||||
level = getattr(meta, "level", PLUGIN_LEVEL_EVENT)
|
||||
if level == PLUGIN_LEVEL_EVENT:
|
||||
if event and hasattr(app, 'is_available'):
|
||||
if not app.is_available(event):
|
||||
|
||||
@@ -81,7 +81,9 @@ from pretix.base.signals import (
|
||||
)
|
||||
from pretix.celery_app import app
|
||||
from pretix.helpers import OF_SELF
|
||||
from pretix.helpers.format import SafeFormatter, format_map
|
||||
from pretix.helpers.format import (
|
||||
FormattedString, PlainHtmlAlternativeString, SafeFormatter, format_map,
|
||||
)
|
||||
from pretix.helpers.hierarkey import clean_filename
|
||||
from pretix.multidomain.urlreverse import build_absolute_uri
|
||||
from pretix.presale.ical import get_private_icals
|
||||
@@ -218,6 +220,9 @@ def mail(email: Union[str, Sequence[str]], subject: str, template: Union[str, La
|
||||
if email == INVALID_ADDRESS:
|
||||
return
|
||||
|
||||
if isinstance(template, FormattedString):
|
||||
raise TypeError("Cannot pass an already formatted body template")
|
||||
|
||||
if no_order_links and not plain_text_only:
|
||||
raise ValueError('If you set no_order_links, you also need to set plain_text_only.')
|
||||
|
||||
@@ -251,23 +256,28 @@ def mail(email: Union[str, Sequence[str]], subject: str, template: Union[str, La
|
||||
if event and attach_tickets and not event.settings.mail_attach_tickets:
|
||||
attach_tickets = False
|
||||
|
||||
with language(locale):
|
||||
with language(locale), override(timezone):
|
||||
if isinstance(context, dict) and order:
|
||||
_autoextend_context(context, order)
|
||||
|
||||
# Build raw content
|
||||
body_plain = render_mail(template, context, placeholder_mode=SafeFormatter.MODE_RICH_TO_PLAIN)
|
||||
content_plain = render_mail(template, context, placeholder_mode=None)
|
||||
if settings_holder:
|
||||
signature = str(settings_holder.settings.get('mail_text_signature'))
|
||||
else:
|
||||
signature = ""
|
||||
|
||||
# Build full plain-text body
|
||||
if not isinstance(content_plain, FormattedString):
|
||||
body_plain = format_map(content_plain, context, mode=SafeFormatter.MODE_RICH_TO_PLAIN)
|
||||
else:
|
||||
body_plain = content_plain
|
||||
body_plain = _wrap_plain_body(body_plain, signature, event, order, position, no_order_links)
|
||||
body_plain = format_map(body_plain, context, mode=SafeFormatter.MODE_RICH_TO_PLAIN)
|
||||
|
||||
# Build subject
|
||||
subject = str(subject).format_map(TolerantDict(context))
|
||||
if not isinstance(subject, FormattedString):
|
||||
subject = format_map(subject, context)
|
||||
|
||||
subject = raw_subject = subject.replace('\n', ' ').replace('\r', '')[:900]
|
||||
if settings_holder:
|
||||
subject = prefix_subject(settings_holder, subject)
|
||||
@@ -286,26 +296,24 @@ def mail(email: Union[str, Sequence[str]], subject: str, template: Union[str, La
|
||||
else:
|
||||
renderer = ClassicMailRenderer(None, organizer)
|
||||
|
||||
with override(timezone):
|
||||
content_plain = render_mail(template, context, placeholder_mode=None)
|
||||
try:
|
||||
if 'context' in inspect.signature(renderer.render).parameters:
|
||||
body_html = renderer.render(content_plain, signature, raw_subject, order, position, context)
|
||||
elif 'position' in inspect.signature(renderer.render).parameters:
|
||||
# Backwards compatibility
|
||||
warnings.warn('Email renderer called without context argument because context argument is not '
|
||||
'supported.',
|
||||
DeprecationWarning)
|
||||
body_html = renderer.render(content_plain, signature, raw_subject, order, position)
|
||||
else:
|
||||
# Backwards compatibility
|
||||
warnings.warn('Email renderer called without position argument because position argument is not '
|
||||
'supported.',
|
||||
DeprecationWarning)
|
||||
body_html = renderer.render(content_plain, signature, raw_subject, order)
|
||||
except:
|
||||
logger.exception('Could not render HTML body')
|
||||
body_html = None
|
||||
try:
|
||||
if 'context' in inspect.signature(renderer.render).parameters:
|
||||
body_html = renderer.render(content_plain, signature, raw_subject, order, position, context)
|
||||
elif 'position' in inspect.signature(renderer.render).parameters:
|
||||
# Backwards compatibility
|
||||
warnings.warn('Email renderer called without context argument because context argument is not '
|
||||
'supported.',
|
||||
DeprecationWarning)
|
||||
body_html = renderer.render(content_plain, signature, raw_subject, order, position)
|
||||
else:
|
||||
# Backwards compatibility
|
||||
warnings.warn('Email renderer called without position argument because position argument is not '
|
||||
'supported.',
|
||||
DeprecationWarning)
|
||||
body_html = renderer.render(content_plain, signature, raw_subject, order)
|
||||
except:
|
||||
logger.exception('Could not render HTML body')
|
||||
body_html = None
|
||||
|
||||
m = OutgoingMail.objects.create(
|
||||
organizer=organizer,
|
||||
@@ -401,6 +409,18 @@ def mail_send_task(self, **kwargs) -> bool:
|
||||
outgoing_mail.inflight_since = now()
|
||||
outgoing_mail.save(update_fields=["status", "inflight_since"])
|
||||
|
||||
# Performance optimization, saves database queries later on if we resolve the known relationships
|
||||
if outgoing_mail.event_id:
|
||||
assert outgoing_mail.event.organizer_id == outgoing_mail.organizer.pk
|
||||
outgoing_mail.event.organizer = outgoing_mail.organizer
|
||||
if outgoing_mail.order_id:
|
||||
assert outgoing_mail.order.event_id == outgoing_mail.event_id
|
||||
outgoing_mail.order.event = outgoing_mail.event
|
||||
outgoing_mail.order.organizer = outgoing_mail.organizer
|
||||
if outgoing_mail.orderposition_id:
|
||||
assert outgoing_mail.orderposition.order_id == outgoing_mail.order_id
|
||||
outgoing_mail.orderposition.order = outgoing_mail.order
|
||||
|
||||
headers = dict(outgoing_mail.headers)
|
||||
headers.setdefault('X-PX-Correlation', str(outgoing_mail.guid))
|
||||
email = CustomEmail(
|
||||
@@ -519,6 +539,7 @@ def mail_send_task(self, **kwargs) -> bool:
|
||||
)
|
||||
except InvoiceAddress.DoesNotExist:
|
||||
pass
|
||||
expected_recipients = {e.lower() for e in expected_recipients if e}
|
||||
if any(t in expected_recipients for t in outgoing_mail.to):
|
||||
invoices_to_mark_transmitted.append(inv)
|
||||
|
||||
@@ -789,7 +810,12 @@ def render_mail(template, context, placeholder_mode: Optional[int]=SafeFormatter
|
||||
body = format_map(body, context, mode=placeholder_mode)
|
||||
else:
|
||||
tpl = get_template(template)
|
||||
body = tpl.render(context)
|
||||
context = {
|
||||
# Known bug, should behave differently for plain and HTML but we'll fix after security release
|
||||
k: v.html if isinstance(v, PlainHtmlAlternativeString) else v
|
||||
for k, v in context.items()
|
||||
}
|
||||
body = FormattedString(tpl.render(context))
|
||||
return body
|
||||
|
||||
|
||||
@@ -935,7 +961,7 @@ def _wrap_plain_body(content_plain, signature, event, order, position, no_order_
|
||||
body_plain += "\r\n\r\n-- \r\n"
|
||||
|
||||
if signature:
|
||||
signature = signature.format(event=event.name if event else '')
|
||||
signature = format_map(signature, {"event": event.name if event else ''})
|
||||
body_plain += signature
|
||||
body_plain += "\r\n\r\n-- \r\n"
|
||||
|
||||
@@ -947,7 +973,7 @@ def _wrap_plain_body(content_plain, signature, event, order, position, no_order_
|
||||
body_plain += _(
|
||||
"You can view your order details at the following URL:\n{orderurl}."
|
||||
).replace("\n", "\r\n").format(
|
||||
event=event.name, orderurl=build_absolute_uri(
|
||||
orderurl=build_absolute_uri(
|
||||
order.event, 'presale:event.order.position', kwargs={
|
||||
'order': order.code,
|
||||
'secret': position.web_secret,
|
||||
|
||||
@@ -247,6 +247,15 @@ def reactivate_order(order: Order, force: bool=False, user: User=None, auth=None
|
||||
for gc in position.issued_gift_cards.all():
|
||||
gc = GiftCard.objects.select_for_update(of=OF_SELF).get(pk=gc.pk)
|
||||
gc.transactions.create(value=position.price, order=order, acceptor=order.event.organizer)
|
||||
gc.log_action(
|
||||
action='pretix.giftcards.transaction.manual',
|
||||
user=user,
|
||||
auth=auth,
|
||||
data={
|
||||
'value': position.price,
|
||||
'acceptor_id': order.event.organizer.id
|
||||
}
|
||||
)
|
||||
break
|
||||
|
||||
for m in position.granted_memberships.all():
|
||||
@@ -548,6 +557,14 @@ def _cancel_order(order, user=None, send_mail: bool=True, api_token=None, device
|
||||
)
|
||||
else:
|
||||
gc.transactions.create(value=-position.price, order=order, acceptor=order.event.organizer)
|
||||
gc.log_action(
|
||||
action='pretix.giftcards.transaction.manual',
|
||||
user=user,
|
||||
data={
|
||||
'value': -position.price,
|
||||
'acceptor_id': order.event.organizer.id,
|
||||
}
|
||||
)
|
||||
|
||||
for m in position.granted_memberships.all():
|
||||
m.canceled = True
|
||||
@@ -2434,6 +2451,15 @@ class OrderChangeManager:
|
||||
))
|
||||
else:
|
||||
gc.transactions.create(value=-position.price, order=self.order, acceptor=self.order.event.organizer)
|
||||
gc.log_action(
|
||||
action='pretix.giftcards.transaction.manual',
|
||||
user=self.user,
|
||||
auth=self.auth,
|
||||
data={
|
||||
'value': -position.price,
|
||||
'acceptor_id': self.order.event.organizer.id
|
||||
}
|
||||
)
|
||||
|
||||
for m in position.granted_memberships.with_usages().all():
|
||||
m.canceled = True
|
||||
@@ -2451,6 +2477,15 @@ class OrderChangeManager:
|
||||
))
|
||||
else:
|
||||
gc.transactions.create(value=-opa.position.price, order=self.order, acceptor=self.order.event.organizer)
|
||||
gc.log_action(
|
||||
action='pretix.giftcards.transaction.manual',
|
||||
user=self.user,
|
||||
auth=self.auth,
|
||||
data={
|
||||
'value': -opa.position.price,
|
||||
'acceptor_id': self.order.event.organizer.id
|
||||
}
|
||||
)
|
||||
|
||||
for m in opa.granted_memberships.with_usages().all():
|
||||
m.canceled = True
|
||||
@@ -3119,7 +3154,10 @@ def _try_auto_refund(order, auto_refund=True, manual_refund=False, allow_partial
|
||||
customer=order.customer,
|
||||
testmode=order.testmode
|
||||
)
|
||||
giftcard.log_action('pretix.giftcards.created', data={})
|
||||
giftcard.log_action(
|
||||
action='pretix.giftcards.created',
|
||||
data={}
|
||||
)
|
||||
r = order.refunds.create(
|
||||
order=order,
|
||||
payment=None,
|
||||
@@ -3406,7 +3444,17 @@ def signal_listener_issue_giftcards(sender: Event, order: Order, **kwargs):
|
||||
currency=sender.currency, issued_in=p, testmode=order.testmode,
|
||||
expires=sender.organizer.default_gift_card_expiry,
|
||||
)
|
||||
gc.transactions.create(value=p.price - issued, order=order, acceptor=sender.organizer)
|
||||
gc.log_action(
|
||||
action='pretix.giftcards.created',
|
||||
)
|
||||
trans = gc.transactions.create(value=p.price - issued, order=order, acceptor=sender.organizer)
|
||||
gc.log_action(
|
||||
action='pretix.giftcards.transaction.manual',
|
||||
data={
|
||||
'value': trans.value,
|
||||
'acceptor_id': order.event.organizer.id,
|
||||
}
|
||||
)
|
||||
any_giftcards = True
|
||||
p.secret = gc.secret
|
||||
p.save(update_fields=['secret'])
|
||||
|
||||
@@ -24,6 +24,7 @@ import logging
|
||||
from datetime import timedelta
|
||||
from decimal import Decimal
|
||||
|
||||
from django.db.models import Prefetch, prefetch_related_objects
|
||||
from django.dispatch import receiver
|
||||
from django.utils.formats import date_format
|
||||
from django.utils.html import escape, mark_safe
|
||||
@@ -35,6 +36,7 @@ from pretix.base.forms.widgets import format_placeholders_help_text
|
||||
from pretix.base.i18n import (
|
||||
LazyCurrencyNumber, LazyDate, LazyExpiresDate, LazyNumber,
|
||||
)
|
||||
from pretix.base.models import EventMetaValue
|
||||
from pretix.base.reldate import RelativeDateWrapper
|
||||
from pretix.base.settings import PERSON_NAME_SCHEMES, get_name_parts_localized
|
||||
from pretix.base.signals import (
|
||||
@@ -752,6 +754,11 @@ def base_placeholders(sender, **kwargs):
|
||||
name_scheme['sample'][f]
|
||||
))
|
||||
|
||||
prefetch_related_objects(
|
||||
[sender],
|
||||
Prefetch('meta_values', queryset=EventMetaValue.objects.select_related("property"), to_attr="meta_values_cached")
|
||||
)
|
||||
prefetch_related_objects([sender.organizer], Prefetch('meta_properties'))
|
||||
for k, v in sender.meta_data.items():
|
||||
ph.append(MarkdownTextPlaceholder(
|
||||
'meta_%s' % k, ['event'], lambda event, k=k: event.meta_data[k],
|
||||
|
||||
@@ -2948,6 +2948,28 @@ If you did not request a new password, please ignore this email.
|
||||
|
||||
Best regards,
|
||||
|
||||
Your {organizer} team""")) # noqa: W291
|
||||
},
|
||||
'mail_subject_customer_security_notice': {
|
||||
'type': LazyI18nString,
|
||||
'default': LazyI18nString.from_gettext(gettext_noop("Changes to your account at {organizer}")),
|
||||
},
|
||||
'mail_text_customer_security_notice': {
|
||||
'type': LazyI18nString,
|
||||
'default': LazyI18nString.from_gettext(gettext_noop("""Hello {name},
|
||||
|
||||
the following change has been made to your account at {organizer}:
|
||||
|
||||
{message}
|
||||
|
||||
You can review and change your account settings here:
|
||||
|
||||
{url}
|
||||
|
||||
If this change was not performed by you, please contact us immediately.
|
||||
|
||||
Best regards,
|
||||
|
||||
Your {organizer} team""")) # noqa: W291
|
||||
},
|
||||
'smtp_use_custom': {
|
||||
|
||||
@@ -60,25 +60,23 @@ def _populate_app_cache():
|
||||
|
||||
def get_defining_app(o):
|
||||
# If sentry packed this in a wrapper, unpack that
|
||||
module = getattr(o, "__module__", None)
|
||||
if module and "sentry" in module:
|
||||
if "sentry" in o.__module__:
|
||||
o = o.__wrapped__
|
||||
|
||||
if hasattr(o, "__mocked_app"):
|
||||
return o.__mocked_app
|
||||
|
||||
# Find the Django application this belongs to
|
||||
searchpath = module or getattr(o.__class__, "__module__", None) or ""
|
||||
searchpath = o.__module__
|
||||
|
||||
# Core modules are always active
|
||||
if searchpath and any(searchpath.startswith(cm) for cm in settings.CORE_MODULES):
|
||||
if any(searchpath.startswith(cm) for cm in settings.CORE_MODULES):
|
||||
return 'CORE'
|
||||
|
||||
if not app_cache:
|
||||
_populate_app_cache()
|
||||
|
||||
app = None
|
||||
while searchpath:
|
||||
while True:
|
||||
app = app_cache.get(searchpath)
|
||||
if "." not in searchpath or app:
|
||||
break
|
||||
@@ -159,11 +157,7 @@ class PluginSignal(Generic[T], django.dispatch.Signal):
|
||||
if not app_cache:
|
||||
_populate_app_cache()
|
||||
|
||||
for receiver in self._sorted_receivers(sender)[0]:
|
||||
if self._is_receiver_active(sender, receiver):
|
||||
response = receiver(signal=self, sender=sender, **named)
|
||||
responses.append((receiver, response))
|
||||
for receiver in self._sorted_receivers(sender)[1]:
|
||||
for receiver in self._sorted_receivers(sender):
|
||||
if self._is_receiver_active(sender, receiver):
|
||||
response = receiver(signal=self, sender=sender, **named)
|
||||
responses.append((receiver, response))
|
||||
@@ -185,11 +179,7 @@ class PluginSignal(Generic[T], django.dispatch.Signal):
|
||||
if not app_cache:
|
||||
_populate_app_cache()
|
||||
|
||||
for receiver in self._sorted_receivers(sender)[0]:
|
||||
if self._is_receiver_active(sender, receiver):
|
||||
named[chain_kwarg_name] = response
|
||||
response = receiver(signal=self, sender=sender, **named)
|
||||
for receiver in self._sorted_receivers(sender)[1]:
|
||||
for receiver in self._sorted_receivers(sender):
|
||||
if self._is_receiver_active(sender, receiver):
|
||||
named[chain_kwarg_name] = response
|
||||
response = receiver(signal=self, sender=sender, **named)
|
||||
@@ -214,15 +204,7 @@ class PluginSignal(Generic[T], django.dispatch.Signal):
|
||||
if not app_cache:
|
||||
_populate_app_cache()
|
||||
|
||||
for receiver in self._sorted_receivers(sender)[0]:
|
||||
if self._is_receiver_active(sender, receiver):
|
||||
try:
|
||||
response = receiver(signal=self, sender=sender, **named)
|
||||
except Exception as err:
|
||||
responses.append((receiver, err))
|
||||
else:
|
||||
responses.append((receiver, response))
|
||||
for receiver in self._sorted_receivers(sender)[1]:
|
||||
for receiver in self._sorted_receivers(sender):
|
||||
if self._is_receiver_active(sender, receiver):
|
||||
try:
|
||||
response = receiver(signal=self, sender=sender, **named)
|
||||
@@ -233,33 +215,16 @@ class PluginSignal(Generic[T], django.dispatch.Signal):
|
||||
return responses
|
||||
|
||||
def _sorted_receivers(self, sender):
|
||||
orig_list_sync = self._live_receivers(sender)[0]
|
||||
# todo: _live_receivers changed return value from [] to [], []
|
||||
orig_list_async = self._live_receivers(sender)[1]
|
||||
|
||||
def _receiver_module(receiver):
|
||||
return getattr(receiver, "__module__", receiver.__class__.__module__)
|
||||
|
||||
def _receiver_name(receiver):
|
||||
return getattr(receiver, "__name__", receiver.__class__.__name__)
|
||||
|
||||
sorted_list_sync = sorted(
|
||||
orig_list_sync,
|
||||
orig_list = self._live_receivers(sender)
|
||||
sorted_list = sorted(
|
||||
orig_list,
|
||||
key=lambda receiver: (
|
||||
0 if any(_receiver_module(receiver).startswith(m) for m in settings.CORE_MODULES) else 1,
|
||||
_receiver_module(receiver),
|
||||
_receiver_name(receiver),
|
||||
0 if any(receiver.__module__.startswith(m) for m in settings.CORE_MODULES) else 1,
|
||||
receiver.__module__,
|
||||
receiver.__name__,
|
||||
)
|
||||
)
|
||||
sorted_list_async = sorted(
|
||||
orig_list_async,
|
||||
key=lambda receiver: (
|
||||
0 if any(_receiver_module(receiver).startswith(m) for m in settings.CORE_MODULES) else 1,
|
||||
_receiver_module(receiver),
|
||||
_receiver_name(receiver),
|
||||
)
|
||||
)
|
||||
return sorted_list_sync, sorted_list_async
|
||||
return sorted_list
|
||||
|
||||
|
||||
class EventPluginSignal(PluginSignal[Event]):
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
# <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
import pycountry
|
||||
from django.conf import settings
|
||||
from django.http import JsonResponse
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.utils.translation import gettext, pgettext, pgettext_lazy
|
||||
@@ -29,6 +30,7 @@ from django_scopes import scope
|
||||
from pretix.base.addressvalidation import (
|
||||
COUNTRIES_WITH_STREET_ZIPCODE_AND_CITY_REQUIRED,
|
||||
)
|
||||
from pretix.base.i18n import language
|
||||
from pretix.base.invoicing.transmission import get_transmission_types
|
||||
from pretix.base.models import Organizer
|
||||
from pretix.base.models.tax import VAT_ID_COUNTRIES
|
||||
@@ -89,7 +91,7 @@ def _info(cc):
|
||||
}
|
||||
|
||||
|
||||
def address_form(request):
|
||||
def _address_form(request):
|
||||
cc = request.GET.get("country", "DE")
|
||||
info = _info(cc)
|
||||
|
||||
@@ -157,4 +159,15 @@ def address_form(request):
|
||||
# The help text explains that it is optional, so we want to hide that if it is required
|
||||
info["vat_id"]["helptext_visible"] = False
|
||||
|
||||
return info
|
||||
|
||||
|
||||
def address_form(request):
|
||||
locale = request.GET.get('locale')
|
||||
if locale in dict(settings.LANGUAGES):
|
||||
with language(locale):
|
||||
info = _address_form(request)
|
||||
else:
|
||||
info = _address_form(request)
|
||||
|
||||
return JsonResponse(info)
|
||||
|
||||
@@ -2820,8 +2820,8 @@ class DeviceFilterForm(FilterForm):
|
||||
|
||||
class OutgoingMailFilterForm(FilterForm):
|
||||
orders = {
|
||||
'date': 'd',
|
||||
'-date': '-d',
|
||||
'date': 'created',
|
||||
'-date': '-created',
|
||||
}
|
||||
query = forms.CharField(
|
||||
label=_('Search email address or subject'),
|
||||
|
||||
@@ -635,6 +635,16 @@ class MailSettingsForm(SettingsForm):
|
||||
required=False,
|
||||
widget=I18nMarkdownTextarea,
|
||||
)
|
||||
mail_subject_customer_security_notice = I18nFormField(
|
||||
label=_("Subject"),
|
||||
required=False,
|
||||
widget=I18nTextInput,
|
||||
)
|
||||
mail_text_customer_security_notice = I18nFormField(
|
||||
label=_("Text"),
|
||||
required=False,
|
||||
widget=I18nMarkdownTextarea,
|
||||
)
|
||||
|
||||
base_context = {
|
||||
'mail_text_customer_registration': ['customer', 'url'],
|
||||
@@ -643,6 +653,8 @@ class MailSettingsForm(SettingsForm):
|
||||
'mail_subject_customer_email_change': ['customer', 'url'],
|
||||
'mail_text_customer_reset': ['customer', 'url'],
|
||||
'mail_subject_customer_reset': ['customer', 'url'],
|
||||
'mail_text_customer_security_notice': ['customer', 'url', 'message'],
|
||||
'mail_subject_customer_security_notice': ['customer', 'url', 'message'],
|
||||
}
|
||||
|
||||
def _get_sample_context(self, base_parameters):
|
||||
@@ -656,6 +668,9 @@ class MailSettingsForm(SettingsForm):
|
||||
'presale:organizer.customer.activate'
|
||||
) + '?token=' + get_random_string(30)
|
||||
|
||||
if 'message' in base_parameters:
|
||||
placeholders['message'] = _('Your password has been changed.')
|
||||
|
||||
if 'customer' in base_parameters:
|
||||
placeholders['name'] = pgettext_lazy('person_name_sample', 'John Doe')
|
||||
name_scheme = PERSON_NAME_SCHEMES[self.organizer.settings.name_scheme]
|
||||
|
||||
@@ -801,6 +801,8 @@ class CoreUserImpersonatedLogEntryType(UserImpersonatedLogEntryType):
|
||||
'pretix.giftcards.created': _('The gift card has been created.'),
|
||||
'pretix.giftcards.modified': _('The gift card has been changed.'),
|
||||
'pretix.giftcards.transaction.manual': _('A manual transaction has been performed.'),
|
||||
'pretix.giftcards.transaction.payment': _('A payment has been performed.'),
|
||||
'pretix.giftcards.transaction.refund': _('A refund has been performed. '),
|
||||
'pretix.team.token.created': _('The token "{name}" has been created.'),
|
||||
'pretix.team.token.deleted': _('The token "{name}" has been revoked.'),
|
||||
'pretix.event.checkin.reset': _('The check-in and print log state has been reset.')
|
||||
|
||||
@@ -65,6 +65,9 @@
|
||||
|
||||
{% blocktrans asvar title_reset %}Customer account password reset{% endblocktrans %}
|
||||
{% include "pretixcontrol/event/mail_settings_fragment.html" with pid="reset" title=title_reset items="mail_subject_customer_reset,mail_text_customer_reset" %}
|
||||
|
||||
{% blocktrans asvar title_security_notice %}Customer account security notification{% endblocktrans %}
|
||||
{% include "pretixcontrol/event/mail_settings_fragment.html" with pid="security_notice" title=title_security_notice items="mail_subject_customer_security_notice,mail_text_customer_security_notice" %}
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
@@ -1226,7 +1226,11 @@ class OrderRefundView(OrderView):
|
||||
customer=order.customer,
|
||||
testmode=order.testmode
|
||||
)
|
||||
giftcard.log_action('pretix.giftcards.created', user=self.request.user, data={})
|
||||
giftcard.log_action(
|
||||
action='pretix.giftcards.created',
|
||||
user=self.request.user,
|
||||
data={}
|
||||
)
|
||||
refunds.append(OrderRefund(
|
||||
order=order,
|
||||
payment=None,
|
||||
|
||||
@@ -1667,9 +1667,12 @@ class GiftCardAcceptanceInviteView(OrganizerDetailViewMixin, OrganizerPermission
|
||||
active=False,
|
||||
)
|
||||
self.request.organizer.log_action(
|
||||
'pretix.giftcards.acceptance.acceptor.invited',
|
||||
data={'acceptor': form.cleaned_data['acceptor'].slug,
|
||||
'reusable_media': form.cleaned_data['reusable_media']},
|
||||
action='pretix.giftcards.acceptance.acceptor.invited',
|
||||
data={
|
||||
'acceptor': form.cleaned_data['acceptor'].slug,
|
||||
'issuer': self.request.organizer.slug,
|
||||
'reusable_media': form.cleaned_data['reusable_media']
|
||||
},
|
||||
user=self.request.user
|
||||
)
|
||||
messages.success(self.request, _('The selected organizer has been invited.'))
|
||||
@@ -1705,8 +1708,11 @@ class GiftCardAcceptanceListView(OrganizerDetailViewMixin, OrganizerPermissionRe
|
||||
).delete()
|
||||
if done:
|
||||
self.request.organizer.log_action(
|
||||
'pretix.giftcards.acceptance.acceptor.removed',
|
||||
data={'acceptor': request.POST.get("delete_acceptor")},
|
||||
action='pretix.giftcards.acceptance.acceptor.removed',
|
||||
data={
|
||||
'acceptor': request.POST.get("delete_acceptor"),
|
||||
'issuer': self.request.organizer.slug
|
||||
},
|
||||
user=request.user
|
||||
)
|
||||
messages.success(self.request, _('The selected connection has been removed.'))
|
||||
@@ -1716,8 +1722,11 @@ class GiftCardAcceptanceListView(OrganizerDetailViewMixin, OrganizerPermissionRe
|
||||
).delete()
|
||||
if done:
|
||||
self.request.organizer.log_action(
|
||||
'pretix.giftcards.acceptance.issuer.removed',
|
||||
data={'issuer': request.POST.get("delete_acceptor")},
|
||||
action='pretix.giftcards.acceptance.issuer.removed',
|
||||
data={
|
||||
'issuer': request.POST.get("delete_acceptor"),
|
||||
'acceptor': self.request.organizer.slug
|
||||
},
|
||||
user=request.user
|
||||
)
|
||||
messages.success(self.request, _('The selected connection has been removed.'))
|
||||
@@ -1727,8 +1736,11 @@ class GiftCardAcceptanceListView(OrganizerDetailViewMixin, OrganizerPermissionRe
|
||||
).update(active=True)
|
||||
if done:
|
||||
self.request.organizer.log_action(
|
||||
'pretix.giftcards.acceptance.issuer.accepted',
|
||||
data={'issuer': request.POST.get("accept_issuer")},
|
||||
action='pretix.giftcards.acceptance.issuer.accepted',
|
||||
data={
|
||||
'issuer': request.POST.get("accept_issuer"),
|
||||
'acceptor': self.request.organizer.slug
|
||||
},
|
||||
user=request.user
|
||||
)
|
||||
messages.success(self.request, _('The selected connection has been accepted.'))
|
||||
@@ -1834,10 +1846,11 @@ class GiftCardDetailView(OrganizerDetailViewMixin, OrganizerPermissionRequiredMi
|
||||
acceptor=request.organizer,
|
||||
)
|
||||
self.object.log_action(
|
||||
'pretix.giftcards.transaction.manual',
|
||||
action='pretix.giftcards.transaction.manual',
|
||||
data={
|
||||
'value': value,
|
||||
'text': request.POST.get('text')
|
||||
'text': request.POST.get('text'),
|
||||
'acceptor_id': self.request.organizer.id
|
||||
},
|
||||
user=self.request.user,
|
||||
)
|
||||
@@ -1886,15 +1899,23 @@ class GiftCardCreateView(OrganizerDetailViewMixin, OrganizerPermissionRequiredMi
|
||||
messages.success(self.request, _('The gift card has been created and can now be used.'))
|
||||
form.instance.issuer = self.request.organizer
|
||||
super().form_valid(form)
|
||||
form.instance.transactions.create(
|
||||
acceptor=self.request.organizer,
|
||||
value=form.cleaned_data['value']
|
||||
form.instance.log_action(
|
||||
action='pretix.giftcards.created',
|
||||
user=self.request.user,
|
||||
)
|
||||
form.instance.log_action('pretix.giftcards.created', user=self.request.user, data={})
|
||||
if form.cleaned_data['value']:
|
||||
form.instance.log_action('pretix.giftcards.transaction.manual', user=self.request.user, data={
|
||||
'value': form.cleaned_data['value']
|
||||
})
|
||||
form.instance.transactions.create(
|
||||
acceptor=self.request.organizer,
|
||||
value=form.cleaned_data['value']
|
||||
)
|
||||
form.instance.log_action(
|
||||
action='pretix.giftcards.transaction.manual',
|
||||
user=self.request.user,
|
||||
data={
|
||||
'value': form.cleaned_data['value'],
|
||||
'acceptor_id': self.request.organizer.id
|
||||
}
|
||||
)
|
||||
return redirect(reverse(
|
||||
'control:organizer.giftcard',
|
||||
kwargs={
|
||||
@@ -1922,7 +1943,11 @@ class GiftCardUpdateView(OrganizerDetailViewMixin, OrganizerPermissionRequiredMi
|
||||
def form_valid(self, form):
|
||||
messages.success(self.request, _('The gift card has been changed.'))
|
||||
super().form_valid(form)
|
||||
form.instance.log_action('pretix.giftcards.modified', user=self.request.user, data=dict(form.cleaned_data))
|
||||
form.instance.log_action(
|
||||
action='pretix.giftcards.modified',
|
||||
user=self.request.user,
|
||||
data=dict(form.cleaned_data)
|
||||
)
|
||||
return redirect(reverse(
|
||||
'control:organizer.giftcard',
|
||||
kwargs={
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
import logging
|
||||
from string import Formatter
|
||||
|
||||
from django.core.exceptions import SuspiciousOperation
|
||||
from django.utils.html import conditional_escape
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -37,6 +38,17 @@ class PlainHtmlAlternativeString:
|
||||
return f"PlainHtmlAlternativeString('{self.plain}', '{self.html}')"
|
||||
|
||||
|
||||
class FormattedString(str):
|
||||
"""
|
||||
A str subclass that has been specifically marked as "already formatted" for email rendering
|
||||
purposes to avoid duplicate formatting.
|
||||
"""
|
||||
__slots__ = ()
|
||||
|
||||
def __str__(self):
|
||||
return self
|
||||
|
||||
|
||||
class SafeFormatter(Formatter):
|
||||
"""
|
||||
Customized version of ``str.format`` that (a) behaves just like ``str.format_map`` and
|
||||
@@ -77,8 +89,19 @@ class SafeFormatter(Formatter):
|
||||
# Ignore format_spec
|
||||
return super().format_field(self._prepare_value(value), '')
|
||||
|
||||
def convert_field(self, value, conversion):
|
||||
# Ignore any conversions
|
||||
if conversion is None:
|
||||
return value
|
||||
else:
|
||||
return str(value)
|
||||
|
||||
def format_map(template, context, raise_on_missing=False, mode=SafeFormatter.MODE_RICH_TO_PLAIN, linkifier=None):
|
||||
|
||||
def format_map(template, context, raise_on_missing=False, mode=SafeFormatter.MODE_RICH_TO_PLAIN, linkifier=None) -> FormattedString:
|
||||
if isinstance(template, FormattedString):
|
||||
raise SuspiciousOperation("Calling format_map() on an already formatted string is likely unsafe.")
|
||||
if not isinstance(template, str):
|
||||
template = str(template)
|
||||
return SafeFormatter(context, raise_on_missing, mode=mode, linkifier=linkifier).format(template)
|
||||
return FormattedString(
|
||||
SafeFormatter(context, raise_on_missing, mode=mode, linkifier=linkifier).format(template)
|
||||
)
|
||||
|
||||
@@ -4,16 +4,16 @@ msgstr ""
|
||||
"Project-Id-Version: 1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-01-26 13:19+0000\n"
|
||||
"PO-Revision-Date: 2025-08-27 22:00+0000\n"
|
||||
"PO-Revision-Date: 2026-02-03 17:12+0000\n"
|
||||
"Last-Translator: Mie Frydensbjerg <mif@aarhus.dk>\n"
|
||||
"Language-Team: Danish <https://translate.pretix.eu/projects/pretix/pretix/da/"
|
||||
">\n"
|
||||
"Language-Team: Danish <https://translate.pretix.eu/projects/pretix/pretix/"
|
||||
"da/>\n"
|
||||
"Language: da\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 5.13\n"
|
||||
"X-Generator: Weblate 5.15.2\n"
|
||||
|
||||
#: pretix/_base_settings.py:87
|
||||
msgid "English"
|
||||
@@ -35175,30 +35175,31 @@ msgid "Yes, request cancellation"
|
||||
msgstr "Generér afbestilling"
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/order_change_confirm.html:19
|
||||
#, fuzzy
|
||||
msgid "Please confirm the following changes to your order."
|
||||
msgstr "Kontroller venligst detaljerne nedenfor og bekræft din bestilling."
|
||||
msgstr "Bekræft venligst følgende ændringer i din ordre."
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/order_giftcard.html:10
|
||||
#: pretix/presale/templates/pretixpresale/event/position_giftcard.html:10
|
||||
#, fuzzy, python-format
|
||||
#, python-format
|
||||
msgid "Gift card: %(code)s"
|
||||
msgstr "Gavekort"
|
||||
msgstr "Gavekort: %(code)s"
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/order_modify.html:5
|
||||
msgid "Modify order"
|
||||
msgstr "Rediger bestilling"
|
||||
msgstr "Redigér ordre"
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/order_modify.html:8
|
||||
#, python-format
|
||||
msgid "Modify order: %(code)s"
|
||||
msgstr ""
|
||||
msgstr "Rediger ordre: %(code)s"
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/order_modify.html:18
|
||||
msgid ""
|
||||
"Modifying your invoice address will not automatically generate a new "
|
||||
"invoice. Please contact us if you need a new invoice."
|
||||
msgstr ""
|
||||
"Ændring af din fakturaadresse vil ikke automatisk generere en ny faktura. "
|
||||
"Kontakt os venligst, hvis du har brug for en ny faktura."
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/order_modify.html:88
|
||||
#: pretix/presale/templates/pretixpresale/event/position_modify.html:49
|
||||
@@ -35210,19 +35211,22 @@ msgid "Change payment method"
|
||||
msgstr "Skift betalingsmetode"
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/order_pay_change.html:13
|
||||
#, fuzzy, python-format
|
||||
#, python-format
|
||||
msgid "Choose payment method: %(code)s"
|
||||
msgstr "Skift betalingsmetode: %(code)s"
|
||||
msgstr "Vælg betalingsmetode: %(code)s"
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/order_pay_change.html:19
|
||||
msgid ""
|
||||
"Please note: If you change your payment method, your order total will change "
|
||||
"by the amount displayed to the right of each method."
|
||||
msgstr ""
|
||||
"Bemærk: Hvis du ændrer din betalingsmetode, ændres din ordres samlede beløb "
|
||||
"med det beløb, der vises til højre for hver metode."
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/order_pay_change.html:61
|
||||
msgid "There are no alternative payment providers available for this order."
|
||||
msgstr ""
|
||||
"Der er ingen alternative betalingsudbydere tilgængelige for denne ordre."
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/order_pay_confirm.html:16
|
||||
msgid "Please confirm the following payment details."
|
||||
@@ -35231,7 +35235,7 @@ msgstr "Bekræft venligst følgende betalingsoplysninger."
|
||||
#: pretix/presale/templates/pretixpresale/event/order_pay_confirm.html:22
|
||||
#, python-format
|
||||
msgid "Total: %(total)s"
|
||||
msgstr ""
|
||||
msgstr "Total: %(total)s"
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/payment_qr_codes.html:17
|
||||
msgid ""
|
||||
@@ -35270,10 +35274,9 @@ msgid ""
|
||||
msgstr ""
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/position.html:63
|
||||
#, fuzzy
|
||||
msgctxt "action"
|
||||
msgid "Change your ticket"
|
||||
msgstr "Ændr pris til"
|
||||
msgstr "Ændr din billet"
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/position.html:68
|
||||
msgid ""
|
||||
@@ -35356,30 +35359,36 @@ msgstr "Aktiver betalingsmetode"
|
||||
#: pretix/presale/templates/pretixpresale/event/voucher.html:36
|
||||
#: pretix/presale/templates/pretixpresale/event/voucher_form.html:9
|
||||
msgid "Voucher redemption"
|
||||
msgstr ""
|
||||
msgstr "Indløsning af rabatkode"
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/voucher.html:20
|
||||
#, fuzzy
|
||||
msgid "This voucher is valid only for the following specific date and time."
|
||||
msgstr "Voucheren er ikke gyldig for denne dato."
|
||||
msgstr "Rabatkoden er ikke gyldig for denne dato."
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/voucher.html:43
|
||||
msgid ""
|
||||
"For the selected date, there are currently no products available that can be "
|
||||
"bought with this voucher. Please try a different date or a different voucher."
|
||||
msgstr ""
|
||||
"Der er i øjeblikket ingen produkter tilgængelige for den valgte dato, som "
|
||||
"kan købes med denne rabatkode. Prøv venligst en anden dato eller en anden "
|
||||
"rabatkode."
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/voucher.html:47
|
||||
msgid ""
|
||||
"There are currently no products available that can be bought with this "
|
||||
"voucher."
|
||||
msgstr ""
|
||||
"Der er i øjeblikket ingen produkter tilgængelige, der kan købes med denne "
|
||||
"rabatkode."
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/voucher.html:52
|
||||
msgid ""
|
||||
"You entered a voucher code that allows you to buy one of the following "
|
||||
"products at the specified price:"
|
||||
msgstr ""
|
||||
"Du har indtastet en rabatkode, der giver dig mulighed for at købe et af "
|
||||
"følgende produkter til den angivne pris:"
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/voucher.html:112
|
||||
#, python-format
|
||||
|
||||
@@ -3,16 +3,16 @@ msgstr ""
|
||||
"Project-Id-Version: HE PRETIX\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-01-26 13:19+0000\n"
|
||||
"PO-Revision-Date: 2025-05-21 10:46+0000\n"
|
||||
"Last-Translator: Raphael Michel <michel@rami.io>\n"
|
||||
"Language-Team: Hebrew <https://translate.pretix.eu/projects/pretix/pretix/he/"
|
||||
">\n"
|
||||
"PO-Revision-Date: 2026-02-09 21:00+0000\n"
|
||||
"Last-Translator: roi belotsercovsky <rbelotsercovsky@gmail.com>\n"
|
||||
"Language-Team: Hebrew <https://translate.pretix.eu/projects/pretix/pretix/"
|
||||
"he/>\n"
|
||||
"Language: he\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: Weblate 5.11.4\n"
|
||||
"X-Generator: Weblate 5.15.2\n"
|
||||
|
||||
#: pretix/_base_settings.py:87
|
||||
msgid "English"
|
||||
@@ -84,7 +84,7 @@ msgstr "יוונית"
|
||||
|
||||
#: pretix/_base_settings.py:104
|
||||
msgid "Hebrew"
|
||||
msgstr ""
|
||||
msgstr "עברית"
|
||||
|
||||
#: pretix/_base_settings.py:105
|
||||
msgid "Indonesian"
|
||||
@@ -140,7 +140,7 @@ msgstr "ספרדית"
|
||||
|
||||
#: pretix/_base_settings.py:118
|
||||
msgid "Spanish (Latin America)"
|
||||
msgstr ""
|
||||
msgstr "ספרדית (אמריקה הלטינית)"
|
||||
|
||||
#: pretix/_base_settings.py:119
|
||||
msgid "Turkish"
|
||||
@@ -285,28 +285,20 @@ msgid "The bundled item must not have bundles on its own."
|
||||
msgstr "הפריט המצורף לא יכול להחזיק חבילות בעצמו."
|
||||
|
||||
#: pretix/api/serializers/item.py:235
|
||||
#, fuzzy
|
||||
#| msgid "The payment is too late to be accepted."
|
||||
msgid "The program start must not be empty."
|
||||
msgstr "התשלום התקבל מאוחר מדי."
|
||||
msgstr "תחילת התוכנית לא יכולה להיות ריקה."
|
||||
|
||||
#: pretix/api/serializers/item.py:239
|
||||
#, fuzzy
|
||||
#| msgid "The payment is too late to be accepted."
|
||||
msgid "The program end must not be empty."
|
||||
msgstr "התשלום התקבל מאוחר מדי."
|
||||
msgstr "סוף התוכנית לא יכול להיות ריק."
|
||||
|
||||
#: pretix/api/serializers/item.py:242 pretix/base/models/items.py:2322
|
||||
#, fuzzy
|
||||
#| msgid "The maximum date must not be before the minimum value."
|
||||
msgid "The program end must not be before the program start."
|
||||
msgstr "התאריך המרבי לא יכול להיות לפני הערך המינימלי."
|
||||
msgstr "סוף התוכנית לא יכול להיות לפני תחילת התוכנית."
|
||||
|
||||
#: pretix/api/serializers/item.py:247 pretix/base/models/items.py:2316
|
||||
#, fuzzy
|
||||
#| msgid "You can not select a subevent if your event is not an event series."
|
||||
msgid "You cannot use program times on an event series."
|
||||
msgstr "לא ניתן לבחור תת-אירוע אם האירוע שלך אינו סדרת אירועים."
|
||||
msgstr "לא ניתן לבחור שעות תוכניות בסדרת אירועים."
|
||||
|
||||
#: pretix/api/serializers/item.py:337
|
||||
#, fuzzy
|
||||
@@ -569,22 +561,15 @@ msgid "Event series date deleted"
|
||||
msgstr "תאריך סדרת אירועים נמחק"
|
||||
|
||||
#: pretix/api/webhooks.py:375
|
||||
#, fuzzy
|
||||
#| msgid "Product name"
|
||||
msgid "Product changed"
|
||||
msgstr "שם המוצר"
|
||||
msgstr "המוצר השתנה"
|
||||
|
||||
#: pretix/api/webhooks.py:376
|
||||
#, fuzzy
|
||||
#| msgid ""
|
||||
#| "Product changed (including product added or deleted and including changes "
|
||||
#| "to nested objects like variations or bundles)"
|
||||
msgid ""
|
||||
"This includes product added or deleted and changes to nested objects like "
|
||||
"variations or bundles."
|
||||
msgstr ""
|
||||
"המוצר שונה (כולל הוספה או מחיקה של מוצר ושינויים לאובייקטים מקוננים כמו "
|
||||
"וריאציות או חבילות)"
|
||||
"זה כולל מוצר שהוסף או נמחק ושונה לאובייקטים מקוננים כמו וריאציות או באנדלים"
|
||||
|
||||
#: pretix/api/webhooks.py:381
|
||||
msgid "Shop taken live"
|
||||
@@ -619,28 +604,22 @@ msgid "Waiting list entry received voucher"
|
||||
msgstr "רשומת רשימת המתנה קיבלה שובר"
|
||||
|
||||
#: pretix/api/webhooks.py:413
|
||||
#, fuzzy
|
||||
#| msgid "Voucher code"
|
||||
msgid "Voucher added"
|
||||
msgstr "קוד שובר"
|
||||
msgstr "קוד שובר הוסף"
|
||||
|
||||
#: pretix/api/webhooks.py:417
|
||||
#, fuzzy
|
||||
#| msgid "Voucher assigned"
|
||||
msgid "Voucher changed"
|
||||
msgstr "שובר הוקצה"
|
||||
msgstr "שובר שונה"
|
||||
|
||||
#: pretix/api/webhooks.py:418
|
||||
msgid ""
|
||||
"Only includes explicit changes to the voucher, not e.g. an increase of the "
|
||||
"number of redemptions."
|
||||
msgstr ""
|
||||
msgstr "כולל רק שינויים מפורשים לשובר, לא למשל העלאת מספר המימושים."
|
||||
|
||||
#: pretix/api/webhooks.py:422
|
||||
#, fuzzy
|
||||
#| msgid "Voucher redeemed"
|
||||
msgid "Voucher deleted"
|
||||
msgstr "שובר מומש"
|
||||
msgstr "שובר נמחק"
|
||||
|
||||
#: pretix/api/webhooks.py:426
|
||||
msgid "Customer account created"
|
||||
@@ -811,7 +790,7 @@ msgstr ""
|
||||
msgid ""
|
||||
"Field \"{field_name}\" does not exist. Please check your {provider_name} "
|
||||
"settings."
|
||||
msgstr ""
|
||||
msgstr "שדה \"{field_name}\" לא קיים. נא לבדוק את הגדרות {provider_name}."
|
||||
|
||||
#: pretix/base/datasync/datasync.py:271
|
||||
#, python-brace-format
|
||||
@@ -819,25 +798,23 @@ msgid ""
|
||||
"Field \"{field_name}\" requires {required_input}, but only got "
|
||||
"{available_inputs}. Please check your {provider_name} settings."
|
||||
msgstr ""
|
||||
"שדה \"{field_name}\" דורש {required_input}, אבל קיבל רק {available_inputs}"
|
||||
". נא לבדוק הגדרות {provider_name}."
|
||||
|
||||
#: pretix/base/datasync/datasync.py:282
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Please update value mapping for field \"{field_name}\" - option \"{val}\" "
|
||||
"not assigned"
|
||||
msgstr ""
|
||||
msgstr "נא לעדכן מיפוי ערכים לשדה \"{field_name}\" - אפשרות \"{val}\" לא מוקצה"
|
||||
|
||||
#: pretix/base/datasync/sourcefields.py:128
|
||||
#, fuzzy
|
||||
#| msgid "Order positions"
|
||||
msgid "Order position details"
|
||||
msgstr "פריטי הזמנה"
|
||||
msgstr "פרטי מצב הזמנה"
|
||||
|
||||
#: pretix/base/datasync/sourcefields.py:129
|
||||
#, fuzzy
|
||||
#| msgid "Attendee email"
|
||||
msgid "Attendee details"
|
||||
msgstr "דוא\"ל משתתף"
|
||||
msgstr "פרטי משתתף"
|
||||
|
||||
#: pretix/base/datasync/sourcefields.py:130 pretix/base/exporters/answers.py:66
|
||||
#: pretix/base/models/items.py:1767 pretix/control/navigation.py:172
|
||||
@@ -847,10 +824,8 @@ msgid "Questions"
|
||||
msgstr "שאלות"
|
||||
|
||||
#: pretix/base/datasync/sourcefields.py:131
|
||||
#, fuzzy
|
||||
#| msgid "Product data"
|
||||
msgid "Product details"
|
||||
msgstr "נתוני מוצר"
|
||||
msgstr "פרטי מוצר"
|
||||
|
||||
#: pretix/base/datasync/sourcefields.py:132
|
||||
#: pretix/control/templates/pretixcontrol/event/settings.html:279
|
||||
@@ -875,17 +850,13 @@ msgid "Invoice address"
|
||||
msgstr "כתובת לחשבונית"
|
||||
|
||||
#: pretix/base/datasync/sourcefields.py:134
|
||||
#, fuzzy
|
||||
#| msgid "Meta information"
|
||||
msgid "Event information"
|
||||
msgstr "מידע מטא"
|
||||
msgstr "מידע על האירוע"
|
||||
|
||||
#: pretix/base/datasync/sourcefields.py:135
|
||||
#, fuzzy
|
||||
#| msgid "Send recovery information"
|
||||
msgctxt "subevent"
|
||||
msgid "Event or date information"
|
||||
msgstr "שלח פרטי שחזור"
|
||||
msgstr "מידע על האירוע או התאריך"
|
||||
|
||||
#: pretix/base/datasync/sourcefields.py:175
|
||||
#: pretix/base/exporters/orderlist.py:638
|
||||
@@ -910,10 +881,8 @@ msgstr "שם משתתף"
|
||||
#: pretix/base/datasync/sourcefields.py:187
|
||||
#: pretix/base/datasync/sourcefields.py:604
|
||||
#: pretix/base/datasync/sourcefields.py:628
|
||||
#, fuzzy
|
||||
#| msgid "Attendee name"
|
||||
msgid "Attendee"
|
||||
msgstr "שם משתתף"
|
||||
msgstr "משתתף"
|
||||
|
||||
#: pretix/base/datasync/sourcefields.py:207
|
||||
#: pretix/base/exporters/orderlist.py:645 pretix/base/forms/questions.py:693
|
||||
@@ -927,10 +896,8 @@ msgid "Attendee email"
|
||||
msgstr "דוא\"ל משתתף"
|
||||
|
||||
#: pretix/base/datasync/sourcefields.py:219
|
||||
#, fuzzy
|
||||
#| msgid "Attendee email"
|
||||
msgid "Attendee or order email"
|
||||
msgstr "דוא\"ל משתתף"
|
||||
msgstr "דוא\"ל משתתף או הזמנה"
|
||||
|
||||
#: pretix/base/datasync/sourcefields.py:232
|
||||
#: pretix/base/exporters/orderlist.py:646 pretix/base/pdf.py:188
|
||||
@@ -943,10 +910,8 @@ msgid "Attendee company"
|
||||
msgstr "חברת המשתתף"
|
||||
|
||||
#: pretix/base/datasync/sourcefields.py:241
|
||||
#, fuzzy
|
||||
#| msgid "Attendee address"
|
||||
msgid "Attendee address street"
|
||||
msgstr "כתובת המשתתף"
|
||||
msgstr "רחוב המשתתף"
|
||||
|
||||
#: pretix/base/datasync/sourcefields.py:250
|
||||
#, fuzzy
|
||||
@@ -955,16 +920,12 @@ msgid "Attendee address ZIP code"
|
||||
msgstr "מיקוד המשתתף"
|
||||
|
||||
#: pretix/base/datasync/sourcefields.py:259
|
||||
#, fuzzy
|
||||
#| msgid "Attendee address"
|
||||
msgid "Attendee address city"
|
||||
msgstr "כתובת המשתתף"
|
||||
msgstr "עיר המשתתף"
|
||||
|
||||
#: pretix/base/datasync/sourcefields.py:268
|
||||
#, fuzzy
|
||||
#| msgid "Attendee address"
|
||||
msgid "Attendee address country"
|
||||
msgstr "כתובת המשתתף"
|
||||
msgstr "מדינת המשתתף"
|
||||
|
||||
#: pretix/base/datasync/sourcefields.py:279
|
||||
#: pretix/base/exporters/orderlist.py:687 pretix/base/pdf.py:346
|
||||
@@ -1000,16 +961,12 @@ msgid "Invoice address country"
|
||||
msgstr "מדינת כתובת לחשבונית"
|
||||
|
||||
#: pretix/base/datasync/sourcefields.py:353
|
||||
#, fuzzy
|
||||
#| msgid "Order details"
|
||||
msgid "Order email"
|
||||
msgstr "פרטי הזמנה"
|
||||
msgstr "דוא\"ל הזמנה"
|
||||
|
||||
#: pretix/base/datasync/sourcefields.py:362
|
||||
#, fuzzy
|
||||
#| msgid "Organizer domain"
|
||||
msgid "Order email domain"
|
||||
msgstr "דומיין מארגן"
|
||||
msgstr "דומיין מייל הזמנה"
|
||||
|
||||
#: pretix/base/datasync/sourcefields.py:371
|
||||
#: pretix/base/exporters/invoices.py:203 pretix/base/exporters/invoices.py:332
|
||||
@@ -1041,10 +998,8 @@ msgid "Order code"
|
||||
msgstr "קוד הזמנה"
|
||||
|
||||
#: pretix/base/datasync/sourcefields.py:380
|
||||
#, fuzzy
|
||||
#| msgid "End order date"
|
||||
msgid "Event and order code"
|
||||
msgstr "תאריך סיום הזמנה"
|
||||
msgstr "אירוע וקוד הזמנה"
|
||||
|
||||
#: pretix/base/datasync/sourcefields.py:389
|
||||
#: pretix/base/exporters/orderlist.py:283 pretix/base/notifications.py:201
|
||||
@@ -1069,16 +1024,12 @@ msgid "Product ID"
|
||||
msgstr "מזהה מוצר"
|
||||
|
||||
#: pretix/base/datasync/sourcefields.py:419
|
||||
#, fuzzy
|
||||
#| msgid "Non-admission product"
|
||||
msgid "Product is admission product"
|
||||
msgstr "מוצר שאינו עבור כניסה"
|
||||
msgstr "מוצר שהינו כרטיס כניסה"
|
||||
|
||||
#: pretix/base/datasync/sourcefields.py:428
|
||||
#, fuzzy
|
||||
#| msgid "Event short name"
|
||||
msgid "Event short form"
|
||||
msgstr "שם האירוע המקוצר"
|
||||
msgstr "טופס האירוע המקוצר"
|
||||
|
||||
#: pretix/base/datasync/sourcefields.py:437 pretix/base/exporters/events.py:57
|
||||
#: pretix/base/exporters/orderlist.py:283
|
||||
@@ -1121,10 +1072,8 @@ msgid "Order code and position number"
|
||||
msgstr "קוד הזמנה ומספר פריט"
|
||||
|
||||
#: pretix/base/datasync/sourcefields.py:482
|
||||
#, fuzzy
|
||||
#| msgid "Ticket page"
|
||||
msgid "Ticket price"
|
||||
msgstr "דף כרטיס"
|
||||
msgstr "מחיר כרטיס"
|
||||
|
||||
#: pretix/base/datasync/sourcefields.py:491 pretix/base/notifications.py:204
|
||||
#: pretix/control/forms/filter.py:220 pretix/control/forms/filter.py:1242
|
||||
@@ -1133,22 +1082,16 @@ msgid "Order status"
|
||||
msgstr "סטטוס הזמנה"
|
||||
|
||||
#: pretix/base/datasync/sourcefields.py:500
|
||||
#, fuzzy
|
||||
#| msgid "Device status"
|
||||
msgid "Ticket status"
|
||||
msgstr "סטטוס מכשיר"
|
||||
msgstr "סטטוס כרטיס"
|
||||
|
||||
#: pretix/base/datasync/sourcefields.py:509
|
||||
#, fuzzy
|
||||
#| msgid "Purchase date and time"
|
||||
msgid "Order date and time"
|
||||
msgstr "תאריך ושעת הקנייה"
|
||||
msgstr "תאריך ושעת ההזמנה"
|
||||
|
||||
#: pretix/base/datasync/sourcefields.py:518
|
||||
#, fuzzy
|
||||
#| msgid "Printing date and time"
|
||||
msgid "Payment date and time"
|
||||
msgstr "תאריך ושעת ההדפסה"
|
||||
msgstr "תאריך ושעת התשלום"
|
||||
|
||||
#: pretix/base/datasync/sourcefields.py:527
|
||||
#: pretix/base/exporters/orderlist.py:292
|
||||
@@ -1159,35 +1102,27 @@ msgid "Order locale"
|
||||
msgstr "שפת הזמנה"
|
||||
|
||||
#: pretix/base/datasync/sourcefields.py:536
|
||||
#, fuzzy
|
||||
#| msgid "Order position"
|
||||
msgid "Order position ID"
|
||||
msgstr "עמדת הזמנה"
|
||||
msgstr "מספר עמדת הזמנה"
|
||||
|
||||
#: pretix/base/datasync/sourcefields.py:545
|
||||
#: pretix/base/exporters/orderlist.py:312
|
||||
#, fuzzy
|
||||
#| msgid "Order time"
|
||||
msgid "Order link"
|
||||
msgstr "שעת הזמנה"
|
||||
msgstr "קישור הזמנה"
|
||||
|
||||
#: pretix/base/datasync/sourcefields.py:560
|
||||
#, fuzzy
|
||||
#| msgid "Ticket block"
|
||||
msgid "Ticket link"
|
||||
msgstr "חסימת כרטיס"
|
||||
msgstr "קישור כרטיס"
|
||||
|
||||
#: pretix/base/datasync/sourcefields.py:578
|
||||
#, fuzzy, python-brace-format
|
||||
#| msgid "Check-in list {val}"
|
||||
#, python-brace-format
|
||||
msgid "Check-in datetime on list {}"
|
||||
msgstr "רשימת הצ'ק-אין {val}"
|
||||
msgstr "צ'ק-אין בתאריך-זמן ברשימה {}"
|
||||
|
||||
#: pretix/base/datasync/sourcefields.py:590
|
||||
#, fuzzy, python-brace-format
|
||||
#| msgid "Question: %(name)s"
|
||||
#, python-brace-format
|
||||
msgid "Question: {name}"
|
||||
msgstr "שאלה: %(name)s"
|
||||
msgstr "שאלה: {name}"
|
||||
|
||||
#: pretix/base/datasync/sourcefields.py:604
|
||||
#: pretix/base/datasync/sourcefields.py:614 pretix/base/settings.py:3691
|
||||
@@ -2328,6 +2263,8 @@ msgid ""
|
||||
"contain at least one position of this product. The order totals etc. still "
|
||||
"include all products contained in the order."
|
||||
msgstr ""
|
||||
"אם אף אחד מהם לא נבחר, כל המוצרים כלולים. הפקודות נכללות אם הן כוללות לפחות "
|
||||
"עמדה אחת של המוצר. סך ההזמנות וכו'. עדיין כולל את כל המוצרים הכלולים בהזמנה."
|
||||
|
||||
#: pretix/base/exporters/orderlist.py:283
|
||||
#: pretix/base/exporters/orderlist.py:478
|
||||
@@ -2591,10 +2528,8 @@ msgid "Voucher"
|
||||
msgstr "שובר"
|
||||
|
||||
#: pretix/base/exporters/orderlist.py:653
|
||||
#, fuzzy
|
||||
#| msgid "Voucher code used:"
|
||||
msgid "Voucher budget usage"
|
||||
msgstr "השתמש בקוד שובר:"
|
||||
msgstr "שימוש בתקציב השוברים"
|
||||
|
||||
#: pretix/base/exporters/orderlist.py:654
|
||||
msgid "Pseudonymization ID"
|
||||
@@ -2686,10 +2621,8 @@ msgid "Check-in lists"
|
||||
msgstr "רשימות צ'ק-אין"
|
||||
|
||||
#: pretix/base/exporters/orderlist.py:706
|
||||
#, fuzzy
|
||||
#| msgid "Resend order link"
|
||||
msgid "Position order link"
|
||||
msgstr "שלח את קישור ההזמנה שוב"
|
||||
msgstr "עמדת קישור הזמנה"
|
||||
|
||||
#: pretix/base/exporters/orderlist.py:876
|
||||
msgid "Order transaction data"
|
||||
@@ -3326,10 +3259,8 @@ msgid "Repeat password"
|
||||
msgstr "חזור על הסיסמה"
|
||||
|
||||
#: pretix/base/forms/auth.py:220 pretix/base/forms/user.py:99
|
||||
#, fuzzy
|
||||
#| msgid "Email address"
|
||||
msgid "Your email address"
|
||||
msgstr "כתובת דוא\"ל"
|
||||
msgstr "כתובת הדוא\"ל שלך"
|
||||
|
||||
#: pretix/base/forms/auth.py:327 pretix/control/forms/orders.py:1041
|
||||
#: pretix/control/templates/pretixcontrol/shredder/download.html:53
|
||||
@@ -3410,14 +3341,12 @@ msgstr ""
|
||||
"למדינתך ומדינת המוכר."
|
||||
|
||||
#: pretix/base/forms/questions.py:1185
|
||||
#, fuzzy
|
||||
#| msgid "Cancellation requested"
|
||||
msgid "No invoice requested"
|
||||
msgstr "בקשת ביטול"
|
||||
msgstr "לא התבקשה חשבונית"
|
||||
|
||||
#: pretix/base/forms/questions.py:1187
|
||||
msgid "Invoice transmission method"
|
||||
msgstr ""
|
||||
msgstr "שיטת שידור חשבונית"
|
||||
|
||||
#: pretix/base/forms/questions.py:1333
|
||||
msgid "You need to provide a company name."
|
||||
@@ -3431,25 +3360,24 @@ msgstr "עליך לספק את שמך."
|
||||
msgid ""
|
||||
"If you enter an invoice address, you also need to select an invoice "
|
||||
"transmission method."
|
||||
msgstr ""
|
||||
msgstr "אם אתה מזין כתובת לחשבונית, עליך גם לבחור שיטת שידור חשבונית."
|
||||
|
||||
#: pretix/base/forms/questions.py:1403
|
||||
#, fuzzy
|
||||
#| msgid "The selected media type is not enabled in your organizer settings."
|
||||
msgid ""
|
||||
"The selected transmission type is not available in your country or for your "
|
||||
"type of address."
|
||||
msgstr "סוג המדיה שנבחר אינו מופעל בהגדרות הארגון שלכם."
|
||||
msgstr "סוג השידור שנבחר אינו זמין במדינתך או בסוג הכתובת שבחרת."
|
||||
|
||||
#: pretix/base/forms/questions.py:1412
|
||||
msgid ""
|
||||
"The selected type of invoice transmission requires a field that is currently "
|
||||
"not available, please reach out to the organizer."
|
||||
msgstr ""
|
||||
"סוג שידור החשבונית שנבחר דורש שדה שאינו זמין כרגע, נא ליצור קשר עם המארגן."
|
||||
|
||||
#: pretix/base/forms/questions.py:1416
|
||||
msgid "This field is required for the selected type of invoice transmission."
|
||||
msgstr ""
|
||||
msgstr "שדה זה הינו חובה לסוג שידור החשבונית שנבחר."
|
||||
|
||||
#: pretix/base/forms/user.py:54 pretix/control/forms/organizer.py:458
|
||||
#: pretix/control/forms/users.py:58
|
||||
@@ -3465,10 +3393,8 @@ msgstr ""
|
||||
"באזור הזמן של האירוע עצמו."
|
||||
|
||||
#: pretix/base/forms/user.py:77
|
||||
#, fuzzy
|
||||
#| msgid "Attendee email address"
|
||||
msgid "Change email address"
|
||||
msgstr "כתובת דוא\"ל של המשתתף"
|
||||
msgstr "שינוי כתובת דוא\"ל"
|
||||
|
||||
#: pretix/base/forms/user.py:83
|
||||
msgid "Device name"
|
||||
@@ -3516,16 +3442,12 @@ msgid ""
|
||||
msgstr "כבר קיים חשבון הקשור לכתובת האימייל הזו. אנא בחר כתובת אחרת."
|
||||
|
||||
#: pretix/base/forms/user.py:179
|
||||
#, fuzzy
|
||||
#| msgid "Email address"
|
||||
msgid "Old email address"
|
||||
msgstr "כתובת דוא\"ל"
|
||||
msgstr "כתובת דוא\"ל ישנה"
|
||||
|
||||
#: pretix/base/forms/user.py:180
|
||||
#, fuzzy
|
||||
#| msgid "Email address"
|
||||
msgid "New email address"
|
||||
msgstr "כתובת דוא\"ל"
|
||||
msgstr "כתובת דוא\"ל חדשה"
|
||||
|
||||
#: pretix/base/forms/validators.py:51
|
||||
msgid ""
|
||||
@@ -3569,60 +3491,47 @@ msgid "Individual customer"
|
||||
msgstr "לקוח פרטי"
|
||||
|
||||
#: pretix/base/invoicing/email.py:50
|
||||
#, fuzzy
|
||||
#| msgid ""
|
||||
#| "Please additionally send my invoice directly to our accounting department"
|
||||
msgid "Email invoice directly to accounting department"
|
||||
msgstr "אנא שלח בנוסף את החשבונית ישירות למחלקת הנהלת החשבונות שלנו"
|
||||
msgstr "שלח חשבונית בדוא\"ל ישירות למחלקת הנהלת חשבונות."
|
||||
|
||||
#: pretix/base/invoicing/email.py:51
|
||||
#, fuzzy
|
||||
#| msgid "The invoice was sent to the designated email address."
|
||||
msgid ""
|
||||
"If not selected, the invoice will be sent to you using the email address "
|
||||
"listed above."
|
||||
msgstr "החשבונית נשלחה לכתובת הדוא\"ל שהוגדרה."
|
||||
msgstr "אם לא ייבחר, בחשבונית תישלח לכתובת הדוא\"ל המצויינת מעלה."
|
||||
|
||||
#: pretix/base/invoicing/email.py:55
|
||||
#, fuzzy
|
||||
#| msgid "Email address verified"
|
||||
msgid "Email address for invoice"
|
||||
msgstr "כתובת דוא\"ל מאומתת"
|
||||
msgstr "כתובת דוא\"ל לחשבונית"
|
||||
|
||||
#: pretix/base/invoicing/email.py:91
|
||||
#, fuzzy
|
||||
#| msgid "Preview email"
|
||||
msgid "PDF via email"
|
||||
msgstr "הצג תצוגה מקדימה של המייל"
|
||||
msgstr "PDF באמצעות דוא\"ל"
|
||||
|
||||
#: pretix/base/invoicing/national.py:37
|
||||
msgctxt "italian_invoice"
|
||||
msgid "Italian Exchange System (SdI)"
|
||||
msgstr ""
|
||||
msgstr "מערכת ההחלפה האיטלקית (SdI)"
|
||||
|
||||
#: pretix/base/invoicing/national.py:38
|
||||
msgctxt "italian_invoice"
|
||||
msgid "Exchange System (SdI)"
|
||||
msgstr ""
|
||||
msgstr "מערכת ההחלפה (SdI)"
|
||||
|
||||
#: pretix/base/invoicing/national.py:51
|
||||
#, fuzzy
|
||||
#| msgid "Gift card code"
|
||||
msgctxt "italian_invoice"
|
||||
msgid "Fiscal code"
|
||||
msgstr "קוד כרטיס מתנה"
|
||||
msgstr "קוד פיסקלי"
|
||||
|
||||
#: pretix/base/invoicing/national.py:55
|
||||
msgctxt "italian_invoice"
|
||||
msgid "Address for certified electronic mail"
|
||||
msgstr ""
|
||||
msgstr "כתובת לדואר אלקטרוני מאושר."
|
||||
|
||||
#: pretix/base/invoicing/national.py:59
|
||||
#, fuzzy
|
||||
#| msgid "Recipient"
|
||||
msgctxt "italian_invoice"
|
||||
msgid "Recipient code"
|
||||
msgstr "נמען"
|
||||
msgstr "קוד נמען"
|
||||
|
||||
#: pretix/base/invoicing/national.py:83
|
||||
msgctxt "italian_invoice"
|
||||
@@ -3632,6 +3541,9 @@ msgid ""
|
||||
"in accordance with the procedures and terms set forth in No. 89757/2018 of "
|
||||
"April 30, 2018, issued by the Director of the Revenue Agency."
|
||||
msgstr ""
|
||||
"קובץ PDF זה הוא העתק ויזואלי של החשבונית ואינו מהווה חשבונית לצרכי מע\"מ. "
|
||||
"החשבונית מונפקת בפורמט XML, ומשודרת בהתאם לנהלים ולתנאים המפורטים בתקנה "
|
||||
"89757/2018 מה30 באפריל, 2016 שפורסמה על ידי מנהל סוכנות ההכנסות."
|
||||
|
||||
#: pretix/base/invoicing/pdf.py:142
|
||||
#, python-format
|
||||
@@ -3812,12 +3724,10 @@ msgid "Remaining amount"
|
||||
msgstr "הסכום שנותר"
|
||||
|
||||
#: pretix/base/invoicing/pdf.py:1008
|
||||
#, fuzzy, python-brace-format
|
||||
#| msgctxt "invoice"
|
||||
#| msgid "Event date: {date_range}"
|
||||
#, python-brace-format
|
||||
msgctxt "invoice"
|
||||
msgid "Invoice period: {daterange}"
|
||||
msgstr "תאריך אירוע: {date_range}"
|
||||
msgstr "תקופת החשבונית: {daterange}"
|
||||
|
||||
#: pretix/base/invoicing/pdf.py:1039
|
||||
msgctxt "invoice"
|
||||
@@ -3880,7 +3790,7 @@ msgstr "תאריך אירוע: {date_range}"
|
||||
#: pretix/base/invoicing/peppol.py:136
|
||||
msgid ""
|
||||
"A Peppol participant ID always starts with a prefix, followed by a colon (:)."
|
||||
msgstr ""
|
||||
msgstr "מזהה משתתף של פפול תמיד מתחיל בתחילית ואחריה נקודתיים(:)."
|
||||
|
||||
#: pretix/base/invoicing/peppol.py:140
|
||||
#, python-format
|
||||
@@ -3888,6 +3798,8 @@ msgid ""
|
||||
"The Peppol participant ID prefix %(number)s is not known to our system. "
|
||||
"Please reach out to us if you are sure this ID is correct."
|
||||
msgstr ""
|
||||
"תחילית מזהה המשתתף של פפול %(number)s אינה מוכרת למערכת. צור עימנו קשר אם "
|
||||
"אתה בטוח שזהו המזהה הנכון."
|
||||
|
||||
#: pretix/base/invoicing/peppol.py:144
|
||||
#, python-format
|
||||
@@ -3895,21 +3807,21 @@ msgid ""
|
||||
"The Peppol participant ID does not match the validation rules for the prefix "
|
||||
"%(number)s. Please reach out to us if you are sure this ID is correct."
|
||||
msgstr ""
|
||||
"מזהה המשתתף של פפול אינו תואם לחוקי הולידציה של התחילית %(number)s. צור "
|
||||
"עימנו קשר אם אתה בטוח שהמזהה נכון."
|
||||
|
||||
#: pretix/base/invoicing/peppol.py:166
|
||||
msgid "The Peppol participant ID is not registered on the Peppol network."
|
||||
msgstr ""
|
||||
msgstr "מזהה המשתתף של פפול אינו רשום ברשת פפול."
|
||||
|
||||
#: pretix/base/invoicing/peppol.py:192
|
||||
msgid "Peppol participant ID"
|
||||
msgstr ""
|
||||
msgstr "מזהה משתתף פפול"
|
||||
|
||||
#: pretix/base/invoicing/peppol.py:208
|
||||
#, fuzzy
|
||||
#| msgid "Gift card code"
|
||||
msgctxt "peppol_invoice"
|
||||
msgid "Visual copy"
|
||||
msgstr "קוד כרטיס מתנה"
|
||||
msgstr "עותק ויזואלי"
|
||||
|
||||
#: pretix/base/invoicing/peppol.py:213
|
||||
msgctxt "peppol_invoice"
|
||||
@@ -3918,6 +3830,8 @@ msgid ""
|
||||
"invoice for VAT purposes. The original invoice is issued in XML format and "
|
||||
"transmitted through the Peppol network."
|
||||
msgstr ""
|
||||
"קובץ PDF זה הינו העתק ויזואלי של החשבונית ואינו מהווה חשבונית לצרכי מע\"מ. "
|
||||
"החשבונית המקורית מופקת בפורמט XML ומשודרת דרך רשת פפול."
|
||||
|
||||
#: pretix/base/logentrytype_registry.py:43
|
||||
msgid ""
|
||||
@@ -4030,7 +3944,7 @@ msgstr "נמצאו מספר תאריכים תואמים."
|
||||
|
||||
#: pretix/base/modelimport_orders.py:73
|
||||
msgid "Grouping"
|
||||
msgstr ""
|
||||
msgstr "קיבוץ"
|
||||
|
||||
#: pretix/base/modelimport_orders.py:75
|
||||
msgid ""
|
||||
@@ -4038,6 +3952,8 @@ msgid ""
|
||||
"together...\". Lines with the same grouping value will be put in the same "
|
||||
"order, but MUST be consecutive lines of the input file."
|
||||
msgstr ""
|
||||
"ישים רק כש\"מצב יבוא\" מוגדר ל\"קיבוץ מספר שורות יחד...\". שורות עם אותו ערך "
|
||||
"קיבוץ יוצבו באותו סדר, אך חייבים להיות שורות רציפות של קובץ הקלט."
|
||||
|
||||
#: pretix/base/modelimport_orders.py:101
|
||||
msgid "Enter a valid phone number."
|
||||
@@ -4049,6 +3965,8 @@ msgid ""
|
||||
"The date can be specified through its full name, full date and time, or "
|
||||
"internal ID, provided only one date in the system matches the input."
|
||||
msgstr ""
|
||||
"התאריך ניתן לציון דרך השם המלא, התאריך והשעה המלאים, או מזהה פנימי בתנאי "
|
||||
"שהמזהה תואם רק תאריך אחד."
|
||||
|
||||
#: pretix/base/modelimport_orders.py:120 pretix/presale/views/waiting.py:157
|
||||
msgctxt "subevent"
|
||||
@@ -4058,7 +3976,7 @@ msgstr "עליך לבחור תאריך."
|
||||
#: pretix/base/modelimport_orders.py:131
|
||||
msgid ""
|
||||
"The product can be specified by its internal ID, full name or internal name."
|
||||
msgstr ""
|
||||
msgstr "המוצר ניתן לציון ע\"י מזהה פנימי, שם מלא או שם פנימי."
|
||||
|
||||
#: pretix/base/modelimport_orders.py:149
|
||||
#: pretix/base/modelimport_vouchers.py:194
|
||||
@@ -4078,7 +3996,7 @@ msgstr "וריאציית מוצר"
|
||||
|
||||
#: pretix/base/modelimport_orders.py:161
|
||||
msgid "The variation can be specified by its internal ID or full name."
|
||||
msgstr ""
|
||||
msgstr "הוריאציה ניתנת לציון לפי מזהה פנימי או שם מלא."
|
||||
|
||||
#: pretix/base/modelimport_orders.py:181
|
||||
#: pretix/base/modelimport_vouchers.py:225
|
||||
@@ -4097,10 +4015,8 @@ msgid "You need to select a variation for this product."
|
||||
msgstr "עליך לבחור וריאציה למוצר זה."
|
||||
|
||||
#: pretix/base/modelimport_orders.py:265 pretix/base/modelimport_orders.py:417
|
||||
#, fuzzy
|
||||
#| msgid "The count needs to be equal to or greater than zero."
|
||||
msgid "The country needs to be specified using a two-letter country code."
|
||||
msgstr "הכמות צריכה להיות שווה או גדולה מאפס."
|
||||
msgstr "המדינה נדרשת להזנה לפי קוד מדינה בין 2 אותיות."
|
||||
|
||||
#: pretix/base/modelimport_orders.py:281 pretix/base/modelimport_orders.py:432
|
||||
msgid "Please enter a valid country code."
|
||||
@@ -4108,7 +4024,7 @@ msgstr "נא להזין קוד ארץ תקין."
|
||||
|
||||
#: pretix/base/modelimport_orders.py:290 pretix/base/modelimport_orders.py:441
|
||||
msgid "The state can be specified by its short form or full name."
|
||||
msgstr ""
|
||||
msgstr "המדינה ניתנת להזנה ע\"י שימוש בקיצור או בשמה המלא."
|
||||
|
||||
#: pretix/base/modelimport_orders.py:300 pretix/base/modelimport_orders.py:450
|
||||
msgid "States are not supported for this country."
|
||||
@@ -4164,17 +4080,15 @@ msgstr "אנא הזן קוד שפה תקין."
|
||||
msgid ""
|
||||
"The sales channel can be specified by it's internal identifier or its full "
|
||||
"name."
|
||||
msgstr ""
|
||||
msgstr "ערוץ המכירה ניתן להזנה ע\"י מזהה פנימי או שם מלא."
|
||||
|
||||
#: pretix/base/modelimport_orders.py:599 pretix/base/modelimport_orders.py:601
|
||||
msgid "Please enter a valid sales channel."
|
||||
msgstr "אנא הזן ערוץ מכירות תקין."
|
||||
|
||||
#: pretix/base/modelimport_orders.py:611
|
||||
#, fuzzy
|
||||
#| msgid "The refund amount needs to be positive and less than {}."
|
||||
msgid "The seat needs to be specified by its internal ID."
|
||||
msgstr "סכום ההחזר חייב להיות חיובי ופחות מ-{}."
|
||||
msgstr "המושב חייב להיות מצויין לפי המזהה הפנימי."
|
||||
|
||||
#: pretix/base/modelimport_orders.py:626
|
||||
#: pretix/base/modelimport_vouchers.py:291
|
||||
@@ -4376,17 +4290,17 @@ msgid ""
|
||||
"to confirm changing your email address from {old_email}\n"
|
||||
"to {new_email}, use the following code:"
|
||||
msgstr ""
|
||||
"לאימות שינוי כתובת הדוא\"ל מ{old_email} \n"
|
||||
"ל {new_email}, השתמש בקוד הבא:"
|
||||
|
||||
#: pretix/base/models/auth.py:377
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"to confirm that your email address {email} belongs to your pretix account, "
|
||||
"use the following code:"
|
||||
msgstr ""
|
||||
msgstr "לאימות שכתובת הדוא\"ל {email} שייכת לחשבונך, השתמש בקוד הבא:"
|
||||
|
||||
#: pretix/base/models/auth.py:391
|
||||
#, fuzzy
|
||||
#| msgid "Confirmation code"
|
||||
msgid "pretix confirmation code"
|
||||
msgstr "קוד אישור"
|
||||
|
||||
@@ -4646,21 +4560,19 @@ msgstr "הפרד בין ערכים מרובים באמצעות רווחים"
|
||||
|
||||
#: pretix/base/models/datasync.py:53
|
||||
msgid "Temporary error, auto-retry limit exceeded"
|
||||
msgstr ""
|
||||
msgstr "שגיאה זמנית, מכסת הניסיונות מחדש האוטומטיים נחרגה"
|
||||
|
||||
#: pretix/base/models/datasync.py:54
|
||||
#, fuzzy
|
||||
#| msgid "Stripe reported an error: %s"
|
||||
msgid "Provider reported a permanent error"
|
||||
msgstr "Stripe דיווח על שגיאה: %s"
|
||||
msgstr "הספק דיווח על שגיאה קבועה"
|
||||
|
||||
#: pretix/base/models/datasync.py:55
|
||||
msgid "Misconfiguration, please check provider settings"
|
||||
msgstr ""
|
||||
msgstr "שגיאת הגדרה, בדוק את הגדרות הספק"
|
||||
|
||||
#: pretix/base/models/datasync.py:56 pretix/base/models/datasync.py:57
|
||||
msgid "System error, needs manual intervention"
|
||||
msgstr ""
|
||||
msgstr "תקלת מערכת, נדרשת התערבות ידנית"
|
||||
|
||||
#: pretix/base/models/devices.py:70 pretix/base/models/items.py:1675
|
||||
msgid "Internal identifier"
|
||||
@@ -4908,13 +4820,15 @@ msgstr "לא חובה. לא יימכרו מוצרים לפני תאריך זה."
|
||||
|
||||
#: pretix/base/models/event.py:644
|
||||
msgid "This event is remote or partially remote."
|
||||
msgstr ""
|
||||
msgstr "אירוע זה הינו אירוע וירטואלי או חלקית וירטואלי."
|
||||
|
||||
#: pretix/base/models/event.py:645
|
||||
msgid ""
|
||||
"This will be used to let users know if the event is in a different timezone "
|
||||
"and let’s us calculate users’ local times."
|
||||
msgstr ""
|
||||
"זה ישמש לעדכן את המשתמשים לדעת אם השעה המצויינת הינה באזור זמן שונה ויאפשר "
|
||||
"לנו לחשב את השעה בהתאם לשעון המקומי של המשתמשים."
|
||||
|
||||
#: pretix/base/models/event.py:665 pretix/base/models/organizer.py:97
|
||||
#: pretix/control/navigation.py:65 pretix/control/navigation.py:499
|
||||
@@ -5191,7 +5105,7 @@ msgstr "יתרה ממתינה"
|
||||
|
||||
#: pretix/base/models/invoices.py:123
|
||||
msgid "currently being transmitted"
|
||||
msgstr ""
|
||||
msgstr "משודר כרגע"
|
||||
|
||||
#: pretix/base/models/invoices.py:124
|
||||
#, fuzzy
|
||||
@@ -6086,6 +6000,8 @@ msgid ""
|
||||
"with changing the type of question without data loss. Consider hiding this "
|
||||
"question and creating a new one instead."
|
||||
msgstr ""
|
||||
"המערכת כבר כוללת תשובות לשאלה זו שאינם מאפשרות שינוי סוג השאלה מבלי לאבד "
|
||||
"מידע. מומלץ לשקול להסתיר את שאלה זו וליצור חדשה במקום."
|
||||
|
||||
#: pretix/base/models/items.py:1961
|
||||
#: pretix/control/templates/pretixcontrol/items/question.html:75
|
||||
@@ -8026,6 +7942,9 @@ msgid ""
|
||||
"2017-05-31 14:00 – 16:00\n"
|
||||
"2017-05-31 14:00 – 2017-06-01 14:00"
|
||||
msgstr ""
|
||||
"2017-05-31 10:00 – 12:00\n"
|
||||
"2017-05-31 14:00 – 16:00\n"
|
||||
"2017-05-31 14:00 – 2017-06-01 14:00"
|
||||
|
||||
#: pretix/base/pdf.py:500
|
||||
msgid "Reusable Medium ID"
|
||||
@@ -8234,7 +8153,7 @@ msgstr "בחרת מוצר שאינו זמין למכירה."
|
||||
msgid ""
|
||||
"Some products can no longer be purchased and have been removed from your "
|
||||
"cart for the following reason: %s"
|
||||
msgstr ""
|
||||
msgstr "חלק מהמוצרים לא ניתנים לרכישה יותר והוסרו מעגלת הקניות מהסיבה הבאה: %s"
|
||||
|
||||
#: pretix/base/services/cart.py:117
|
||||
msgid ""
|
||||
@@ -8984,7 +8903,7 @@ msgstr "ההזמנה אינה יכולה להכיל יותר מ־%(max)s עמד
|
||||
msgid ""
|
||||
"The grouping \"%(value)s\" occurs on non-consecutive lines (seen again on "
|
||||
"line %(row)s)."
|
||||
msgstr ""
|
||||
msgstr "הקיבוץ \"%(value)s\" מתקיים בשורות לא רציפות (נראה שוב בשורה %(row)s)."
|
||||
|
||||
#: pretix/base/services/modelimport.py:154
|
||||
#, python-brace-format
|
||||
@@ -8992,6 +8911,8 @@ msgid ""
|
||||
"Inconsistent data in row {row}: Column {col} contains value \"{val_line}\", "
|
||||
"but for this order, the value has already been set to \"{val_order}\"."
|
||||
msgstr ""
|
||||
"מידע לא רציף בשורה {row}: טור {col} מכיל ערך \"{val_line}\", אך להזמנה זו, "
|
||||
"הערך כבר הוגדר ל \"{val_order}\"."
|
||||
|
||||
#: pretix/base/services/modelimport.py:168
|
||||
#: pretix/base/services/modelimport.py:289
|
||||
@@ -9433,15 +9354,15 @@ msgstr "השובר נשלח ל-{recipient}."
|
||||
|
||||
#: pretix/base/settings.py:82
|
||||
msgid "Compute taxes for every line individually"
|
||||
msgstr ""
|
||||
msgstr "חשב מיסים לכל שורה בנפרד"
|
||||
|
||||
#: pretix/base/settings.py:83
|
||||
msgid "Compute taxes based on net total"
|
||||
msgstr ""
|
||||
msgstr "חשב מיסים תוך ביסוס על סה\"כ נטו"
|
||||
|
||||
#: pretix/base/settings.py:84
|
||||
msgid "Compute taxes based on net total with stable gross prices"
|
||||
msgstr ""
|
||||
msgstr "חשב מיסים על סה\"כ נטו עם ברוטו יציב"
|
||||
|
||||
#: pretix/base/settings.py:134
|
||||
msgid "Allow usage of restricted plugins"
|
||||
@@ -9470,7 +9391,7 @@ msgstr "אם אפשרות זו מושבתת, תצטרך לחבר ספקי זיה
|
||||
|
||||
#: pretix/base/settings.py:189
|
||||
msgid "Require login to access order confirmation pages"
|
||||
msgstr ""
|
||||
msgstr "דרוש כניסה למשתמש על מנת לגשת לדפי אישור הזמנה"
|
||||
|
||||
#: pretix/base/settings.py:190
|
||||
msgid ""
|
||||
@@ -9479,6 +9400,9 @@ msgid ""
|
||||
"placing an order, the restriction only becomes active after the customer "
|
||||
"account is activated."
|
||||
msgstr ""
|
||||
"אם מופעל, משתמשים שהיו מחוברים לאתר בזמן רכישה יצטרכו להתחבר לחשבונם באתר על "
|
||||
"מנת לגשת לפרטי ההזמנה שלהם. אם החשבון נוצר במהלך הרכישה, ההגבלה נכנסת לתוקף "
|
||||
"רק לאחר הפעלת החשבון."
|
||||
|
||||
#: pretix/base/settings.py:202
|
||||
msgid "Match orders based on email address"
|
||||
@@ -9658,6 +9582,8 @@ msgid ""
|
||||
"for tax reporting, you need to make sure to account for possible rounding "
|
||||
"differences if your external system rounds differently than pretix."
|
||||
msgstr ""
|
||||
"שים לב- במידה ותייצא את נתוני המכירות שלך למערכת חיצונית לדיווח מס, עלייך "
|
||||
"לקחת בחשבון כי ייתכנו פערים אם המערכת החיצונית מבצעת עיגול בצורה שונה."
|
||||
|
||||
#: pretix/base/settings.py:514
|
||||
msgid "Ask for invoice address"
|
||||
@@ -9786,6 +9712,8 @@ msgid ""
|
||||
"ID in all countries. VAT ID will be required for all business addresses in "
|
||||
"the selected countries."
|
||||
msgstr ""
|
||||
"מספר עסק מגדר כרשות כברירת מחדל מאחר ובחלק מהמדינות ישנם עסקים שלא מוקצה להם "
|
||||
"מספר עסק. מספר עסק יוגדר כחובה בכל המדינות הנבחרות."
|
||||
|
||||
#: pretix/base/settings.py:685
|
||||
msgid "Invoice address explanation"
|
||||
@@ -10172,10 +10100,12 @@ msgid ""
|
||||
"Automatic based on ticket-specific validity, membership validity, event "
|
||||
"series date, or event date"
|
||||
msgstr ""
|
||||
"אוטומטי בהתאם לזמינות הכרטיס הספציפי, זמינות המנוי, תאריכי סדרת האירועים או "
|
||||
"תאריך האירוע"
|
||||
|
||||
#: pretix/base/settings.py:1179 pretix/base/settings.py:1190
|
||||
msgid "Automatic, but prefer invoice date over event date"
|
||||
msgstr ""
|
||||
msgstr "אוטומטי, אבל העדף תאריך חשבונית על תאריך אירוע"
|
||||
|
||||
#: pretix/base/settings.py:1182 pretix/base/settings.py:1193
|
||||
#, fuzzy
|
||||
@@ -10196,6 +10126,7 @@ msgid ""
|
||||
"This controls what dates are shown on the invoice, but is especially "
|
||||
"important for electronic invoicing."
|
||||
msgstr ""
|
||||
"זה שולט על איזה תאריכים מוצגים על החשבונית, ובמיוחד חשוב לחשבוניות דיגיטליות."
|
||||
|
||||
#: pretix/base/settings.py:1206
|
||||
msgid "Automatically cancel and reissue invoice on address changes"
|
||||
@@ -12767,7 +12698,7 @@ msgstr "אם זה לוקח יותר מכמה דקות, רענן את הדף או
|
||||
#: pretix/base/templates/pretixbase/email/cancel_confirm.txt:2
|
||||
msgid ""
|
||||
"You have requested us to cancel an event which includes a larger bulk-refund:"
|
||||
msgstr ""
|
||||
msgstr "ביקשת מאיתנו לבטל אירוע שכולל החזר כספי גדול יותר:"
|
||||
|
||||
#: pretix/base/templates/pretixbase/email/cancel_confirm.txt:6
|
||||
#, fuzzy
|
||||
@@ -12780,6 +12711,7 @@ msgid ""
|
||||
"Please confirm that you want to proceed by coping the following confirmation "
|
||||
"code into the cancellation form:"
|
||||
msgstr ""
|
||||
"נא לאשר שברצונך להמשיך באמצעות העתקה של קוד האימות הבא לתוך טופס הביטול:"
|
||||
|
||||
#: pretix/base/templates/pretixbase/email/email_footer.html:3
|
||||
#, python-format
|
||||
@@ -13457,7 +13389,7 @@ msgstr "כל השערים"
|
||||
|
||||
#: pretix/control/forms/checkin.py:222
|
||||
msgid "I am sure that the check-in state of the entire event should be reset."
|
||||
msgstr ""
|
||||
msgstr "אני בטוח שמצב הצ'ק אין של האירוע צריך לעבור איפוס."
|
||||
|
||||
#: pretix/control/forms/event.py:91
|
||||
msgid "Use languages"
|
||||
@@ -13556,7 +13488,7 @@ msgstr "ברירת מחדל ({value})"
|
||||
|
||||
#: pretix/control/forms/event.py:381
|
||||
msgid "The currency cannot be changed because orders already exist."
|
||||
msgstr ""
|
||||
msgstr "לא ניתן לבצע שינוי בסוג המטבע מאחר והזמנות כבר קיימות."
|
||||
|
||||
#: pretix/control/forms/event.py:392 pretix/control/forms/event.py:405
|
||||
msgid "Domain"
|
||||
@@ -13644,7 +13576,7 @@ msgstr "כולל כל המיסים"
|
||||
|
||||
#: pretix/control/forms/event.py:815
|
||||
msgid "Recommended if you sell tickets at least partly to consumers."
|
||||
msgstr ""
|
||||
msgstr "מומלץ אם תמכור כרטיסים לפחות חלקית ללקוחות."
|
||||
|
||||
#: pretix/control/forms/event.py:819
|
||||
#, fuzzy
|
||||
@@ -13655,7 +13587,7 @@ msgstr "כל העתיד (לא כולל היום)"
|
||||
|
||||
#: pretix/control/forms/event.py:820
|
||||
msgid "Recommended only if you sell tickets primarily to business customers."
|
||||
msgstr ""
|
||||
msgstr "מומלץ רק אם תמכור כרטיסים בעיקר ללקוחות עסקיים."
|
||||
|
||||
#: pretix/control/forms/event.py:856
|
||||
#, fuzzy
|
||||
@@ -13885,6 +13817,7 @@ msgid ""
|
||||
"This will only be used if the invoice is sent to a different email address "
|
||||
"or at a different time than the order confirmation."
|
||||
msgstr ""
|
||||
"זה ישומש רק אם החשבונית תישלח לכתובת מייל אחרת או בזמן אחר מאישור ההזמנה."
|
||||
|
||||
#: pretix/control/forms/event.py:1321
|
||||
msgid ""
|
||||
@@ -14335,7 +14268,7 @@ msgstr "שולם"
|
||||
#: pretix/control/forms/filter.py:1304
|
||||
msgctxt "subevent"
|
||||
msgid "Date doesn't start in selected date range."
|
||||
msgstr ""
|
||||
msgstr "תאריך לא מתחיל בטווח התאריכים שנבחר."
|
||||
|
||||
#: pretix/control/forms/filter.py:1360 pretix/control/forms/filter.py:1827
|
||||
msgid "Shop live and presale running"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,8 +8,8 @@ msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-01-26 13:19+0000\n"
|
||||
"PO-Revision-Date: 2025-12-19 00:00+0000\n"
|
||||
"Last-Translator: Daniel Branda <daniel.branda.ad@gmail.com>\n"
|
||||
"PO-Revision-Date: 2026-02-10 16:49+0000\n"
|
||||
"Last-Translator: Michele Pagnozzi <michele.pagnozzi@gmail.com>\n"
|
||||
"Language-Team: Italian <https://translate.pretix.eu/projects/pretix/pretix/"
|
||||
"it/>\n"
|
||||
"Language: it\n"
|
||||
@@ -17,7 +17,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 5.15\n"
|
||||
"X-Generator: Weblate 5.15.2\n"
|
||||
|
||||
#: pretix/_base_settings.py:87
|
||||
msgid "English"
|
||||
@@ -966,7 +966,7 @@ msgstr "Indirizzo di fatturazione dell'azienda"
|
||||
#: pretix/base/exporters/orderlist.py:688
|
||||
#: pretix/base/exporters/orderlist.py:692 pretix/base/pdf.py:341
|
||||
msgid "Invoice address name"
|
||||
msgstr "Nome dell'indirizzo di fatturazione"
|
||||
msgstr "Indirizzo di fatturazione"
|
||||
|
||||
#: pretix/base/datasync/sourcefields.py:317
|
||||
#: pretix/base/exporters/orderlist.py:694 pretix/base/pdf.py:351
|
||||
|
||||
@@ -8,8 +8,8 @@ msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-01-26 09:10+0000\n"
|
||||
"PO-Revision-Date: 2025-05-05 09:40+0000\n"
|
||||
"Last-Translator: \"Luca Martinelli [Sannita]\" <sannita@gmail.com>\n"
|
||||
"PO-Revision-Date: 2026-02-10 16:49+0000\n"
|
||||
"Last-Translator: Raffaele Doretto <ced@comune.portogruaro.ve.it>\n"
|
||||
"Language-Team: Italian <https://translate.pretix.eu/projects/pretix/pretix-"
|
||||
"js/it/>\n"
|
||||
"Language: it\n"
|
||||
@@ -17,7 +17,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 5.11.1\n"
|
||||
"X-Generator: Weblate 5.15.2\n"
|
||||
|
||||
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
|
||||
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
|
||||
@@ -1134,6 +1134,9 @@ msgid ""
|
||||
"add yourself to the waiting list. We will then notify if seats are available "
|
||||
"again."
|
||||
msgstr ""
|
||||
"Alcune o tutte le categorie di biglietti sono attualmente esaurite. Se lo "
|
||||
"desideri, puoi aggiungerti alla lista d'attesa. Ti informeremo se i posti "
|
||||
"saranno nuovamente disponibili."
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:76
|
||||
msgctxt "widget"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,8 +8,8 @@ msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-01-26 09:10+0000\n"
|
||||
"PO-Revision-Date: 2026-01-28 18:00+0000\n"
|
||||
"Last-Translator: Ryo Tagami <rtagami@airstrip.jp>\n"
|
||||
"PO-Revision-Date: 2026-02-12 20:00+0000\n"
|
||||
"Last-Translator: Yasunobu YesNo Kawaguchi <kawaguti@gmail.com>\n"
|
||||
"Language-Team: Japanese <https://translate.pretix.eu/projects/pretix/pretix-"
|
||||
"js/ja/>\n"
|
||||
"Language: ja\n"
|
||||
@@ -27,7 +27,7 @@ msgstr "支払い済み"
|
||||
|
||||
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:76
|
||||
msgid "Comment:"
|
||||
msgstr "注釈:"
|
||||
msgstr "コメント:"
|
||||
|
||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:34
|
||||
msgid "PayPal"
|
||||
@@ -157,7 +157,7 @@ msgstr "受注件数"
|
||||
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:15
|
||||
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:63
|
||||
msgid "Paid orders"
|
||||
msgstr "支払い済みの注文"
|
||||
msgstr "支払い済み件数"
|
||||
|
||||
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:27
|
||||
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:39
|
||||
@@ -167,7 +167,7 @@ msgstr "参加者 (注文済み)"
|
||||
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:27
|
||||
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:39
|
||||
msgid "Attendees (paid)"
|
||||
msgstr "参加者 (有料)"
|
||||
msgstr "参加者 (支払い済み)"
|
||||
|
||||
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:51
|
||||
msgid "Total revenue"
|
||||
@@ -215,7 +215,7 @@ msgstr "このチケットは特別な対応が必要です"
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:37
|
||||
msgid "Switch direction"
|
||||
msgstr "方向転換"
|
||||
msgstr "向きを切り替え"
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:38
|
||||
msgid "Entry"
|
||||
@@ -223,7 +223,7 @@ msgstr "入場"
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:39
|
||||
msgid "Exit"
|
||||
msgstr "退出"
|
||||
msgstr "退場"
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:40
|
||||
msgid "Scan a ticket or search and press return…"
|
||||
@@ -297,7 +297,7 @@ msgstr "不明なチケット"
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:59
|
||||
msgid "Ticket type not allowed here"
|
||||
msgstr "この種類のチケットは使用できません"
|
||||
msgstr "この種類のチケットはここでは使用できません"
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:61
|
||||
msgid "Entry not allowed"
|
||||
@@ -321,7 +321,7 @@ msgstr "注文がキャンセルされました"
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:66
|
||||
msgid "Ticket code is ambiguous on list"
|
||||
msgstr "リストのチケットコードは曖昧です"
|
||||
msgstr "リスト上でチケットコードが一意に特定できません"
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:67
|
||||
msgid "Order not approved"
|
||||
@@ -358,7 +358,7 @@ msgstr "閉じる"
|
||||
#: pretix/static/pretixbase/js/addressform.js:101
|
||||
#: pretix/static/pretixpresale/js/ui/main.js:529
|
||||
msgid "required"
|
||||
msgstr "必要"
|
||||
msgstr "必須"
|
||||
|
||||
#: pretix/static/pretixbase/js/asynctask.js:13
|
||||
msgid ""
|
||||
@@ -370,8 +370,7 @@ msgstr ""
|
||||
|
||||
#: pretix/static/pretixbase/js/asynctask.js:17
|
||||
msgid "Your request has been queued on the server and will soon be processed."
|
||||
msgstr ""
|
||||
"サーバへ送信されたリクエスト順にお応えしています。今しばらくお待ちください。"
|
||||
msgstr "お客様のリクエストはサーバーで受け付けられました。まもなく処理されます。"
|
||||
|
||||
#: pretix/static/pretixbase/js/asynctask.js:21
|
||||
msgid ""
|
||||
@@ -394,8 +393,7 @@ msgstr "{code} のエラーが発生しました。"
|
||||
msgid ""
|
||||
"We currently cannot reach the server, but we keep trying. Last error code: "
|
||||
"{code}"
|
||||
msgstr ""
|
||||
"現在サーバへの接続ができませんが、接続試行中です。エラーコード: {code}"
|
||||
msgstr "現在サーバへの接続ができませんが、接続試行中です。最新のエラーコード: {code}"
|
||||
|
||||
#: pretix/static/pretixbase/js/asynctask.js:162
|
||||
#: pretix/static/pretixcontrol/js/ui/mail.js:21
|
||||
@@ -419,9 +417,8 @@ msgid ""
|
||||
"than one minute, please check your internet connection and then reload this "
|
||||
"page and try again."
|
||||
msgstr ""
|
||||
"リクエストがサーバへ送信されました。1分以上経っても応答がない場合は、イン"
|
||||
"ターネット接続を確認してください。確認完了後、ウェブページを再度読込み、再試"
|
||||
"行してください。"
|
||||
"現在リクエストをサーバへ送信中です。1分以上経っても応答がない場合は、"
|
||||
"インターネット接続を確認し、このページを再読み込みして再試行してください。"
|
||||
|
||||
#: pretix/static/pretixbase/js/asynctask.js:276
|
||||
msgid "If this takes longer than a few minutes, please contact us."
|
||||
@@ -429,7 +426,7 @@ msgstr "数分以上かかる場合は、お問い合わせください。"
|
||||
|
||||
#: pretix/static/pretixbase/js/asynctask.js:331
|
||||
msgid "Close message"
|
||||
msgstr "閉じる"
|
||||
msgstr "メッセージを閉じる"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/clipboard.js:23
|
||||
msgid "Copied!"
|
||||
@@ -443,7 +440,7 @@ msgstr "Ctrl-Cを押してコピー!"
|
||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:18
|
||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:24
|
||||
msgid "is one of"
|
||||
msgstr "の一つです"
|
||||
msgstr "次のいずれか"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:30
|
||||
msgid "is before"
|
||||
@@ -523,7 +520,7 @@ msgstr "以下のすべての条件(AND)"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:183
|
||||
msgid "At least one of the conditions below (OR)"
|
||||
msgstr "以下の条件のうち、最低1つ(または)"
|
||||
msgstr "以下の条件のうち、最低1つ(OR)"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:184
|
||||
msgid "Event start"
|
||||
@@ -564,16 +561,16 @@ msgstr "複製"
|
||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:193
|
||||
msgctxt "entry_status"
|
||||
msgid "present"
|
||||
msgstr "出席"
|
||||
msgstr "入場中"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:194
|
||||
msgctxt "entry_status"
|
||||
msgid "absent"
|
||||
msgstr "欠席"
|
||||
msgstr "未入場"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:289
|
||||
msgid "Error: Product not found!"
|
||||
msgstr "エラー:製品が見つかりません!"
|
||||
msgstr "エラー:商品が見つかりません!"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:296
|
||||
msgid "Error: Variation not found!"
|
||||
@@ -585,7 +582,7 @@ msgstr "チェックイン用QRコード"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:549
|
||||
msgid "The PDF background file could not be loaded for the following reason:"
|
||||
msgstr "以下の理由によりPDFファイルの読み込みに失敗しました:"
|
||||
msgstr "以下の理由によりPDF背景ファイルの読み込みに失敗しました:"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:904
|
||||
msgid "Group of objects"
|
||||
@@ -593,7 +590,7 @@ msgstr "オブジェクトグループ"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:909
|
||||
msgid "Text object (deprecated)"
|
||||
msgstr "テキストオブジェクト (廃止済)"
|
||||
msgstr "テキストオブジェクト(非推奨)"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:911
|
||||
msgid "Text box"
|
||||
@@ -609,7 +606,7 @@ msgstr "画像エリア"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:917
|
||||
msgid "Powered by pretix"
|
||||
msgstr "Pretixのイベントチケット売り場"
|
||||
msgstr "Powered by pretix"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:919
|
||||
msgid "Object"
|
||||
@@ -647,24 +644,24 @@ msgstr "不明なエラー。"
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:309
|
||||
msgid "Your color has great contrast and will provide excellent accessibility."
|
||||
msgstr ""
|
||||
"あなたの色は素晴らしいコントラストを持ち、優れたアクセシビリティを提供しま"
|
||||
"す。"
|
||||
"選択した色は素晴らしいコントラストを持ち、優れたアクセシビリティを提供します"
|
||||
"。"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:313
|
||||
msgid ""
|
||||
"Your color has decent contrast and is sufficient for minimum accessibility "
|
||||
"requirements."
|
||||
msgstr ""
|
||||
"あなたの色は適切なコントラストを持ち、最小限のアクセシビリティ要件に十分で"
|
||||
"す。"
|
||||
"選択した色は適切なコントラストを持ち、最小限のアクセシビリティ要件に十分です"
|
||||
"。"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:317
|
||||
msgid ""
|
||||
"Your color has insufficient contrast to white. Accessibility of your site "
|
||||
"will be impacted."
|
||||
msgstr ""
|
||||
"あなたの色は白に対して十分なコントラストがありません。サイトのアクセシビリ"
|
||||
"ティに影響します。"
|
||||
"選択した色は白に対して十分なコントラストがありません。サイトの"
|
||||
"アクセシビリティに影響します。"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:443
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:463
|
||||
@@ -677,7 +674,7 @@ msgstr "全て"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:462
|
||||
msgid "None"
|
||||
msgstr "ない"
|
||||
msgstr "なし"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:466
|
||||
msgid "Selected only"
|
||||
@@ -693,7 +690,7 @@ msgstr "無効なページ番号。"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1000
|
||||
msgid "Use a different name internally"
|
||||
msgstr "内部で別の名前を使用してください"
|
||||
msgstr "内部で別の名前を使用する"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1040
|
||||
msgid "Click to close"
|
||||
@@ -722,15 +719,15 @@ msgstr "カウント"
|
||||
#: pretix/static/pretixcontrol/js/ui/subevent.js:112
|
||||
msgid "(one more date)"
|
||||
msgid_plural "({num} more dates)"
|
||||
msgstr[0] "({num} 他の日程)"
|
||||
msgstr[0] "(他に{num}件の日程)"
|
||||
|
||||
#: pretix/static/pretixpresale/js/ui/cart.js:47
|
||||
msgid ""
|
||||
"The items in your cart are no longer reserved for you. You can still "
|
||||
"complete your order as long as they’re available."
|
||||
msgstr ""
|
||||
"カートに入っている商品は現在売り切れです。在庫があれば、このまま注文を完了す"
|
||||
"ることができます。"
|
||||
"カート内のアイテムの予約が解除されました。在庫がある限り、引き続き注文を完了"
|
||||
"できます。"
|
||||
|
||||
#: pretix/static/pretixpresale/js/ui/cart.js:49
|
||||
msgid "Cart expired"
|
||||
@@ -744,27 +741,27 @@ msgstr "カートの有効期限が近づいています。"
|
||||
#: pretix/static/pretixpresale/js/ui/cart.js:62
|
||||
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."
|
||||
msgstr[0] "カート内の商品の予約は {num} 分以内に完了します。"
|
||||
msgstr[0] "カート内の商品はあと {num} 分間確保されています。"
|
||||
|
||||
#: pretix/static/pretixpresale/js/ui/cart.js:83
|
||||
msgid "Your cart has expired."
|
||||
msgstr "カートの保存期限が切れています。"
|
||||
msgstr "カートの有効期限が切れています。"
|
||||
|
||||
#: pretix/static/pretixpresale/js/ui/cart.js:86
|
||||
msgid ""
|
||||
"The items in your cart are no longer reserved for you. You can still "
|
||||
"complete your order as long as they're available."
|
||||
msgstr ""
|
||||
"カート内の商品の予約期限が切れました。在庫があれば、このまま注文を完了するこ"
|
||||
"カート内の商品の確保期限が切れました。在庫があれば、このまま注文を完了するこ"
|
||||
"とができます。"
|
||||
|
||||
#: pretix/static/pretixpresale/js/ui/cart.js:87
|
||||
msgid "Do you want to renew the reservation period?"
|
||||
msgstr "予約の期間を更新しますか?"
|
||||
msgstr "確保期間を更新しますか?"
|
||||
|
||||
#: pretix/static/pretixpresale/js/ui/cart.js:90
|
||||
msgid "Renew reservation"
|
||||
msgstr "予約を更新"
|
||||
msgstr "確保を更新"
|
||||
|
||||
#: pretix/static/pretixpresale/js/ui/main.js:194
|
||||
msgid "The organizer keeps %(currency)s %(amount)s"
|
||||
@@ -780,7 +777,7 @@ msgstr "主催者が留保する料金を入力してください。"
|
||||
|
||||
#: pretix/static/pretixpresale/js/ui/main.js:577
|
||||
msgid "Your local time:"
|
||||
msgstr "現地時間:"
|
||||
msgstr "お使いの地域の時刻:"
|
||||
|
||||
#: pretix/static/pretixpresale/js/walletdetection.js:39
|
||||
msgid "Google Pay"
|
||||
@@ -863,7 +860,7 @@ msgstr "登録"
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:30
|
||||
msgctxt "widget"
|
||||
msgid "Reserved"
|
||||
msgstr "予約完了"
|
||||
msgstr "予約済み"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:31
|
||||
msgctxt "widget"
|
||||
@@ -879,7 +876,7 @@ msgstr "%(currency)s %(price)sから"
|
||||
#, javascript-format
|
||||
msgctxt "widget"
|
||||
msgid "Image of %s"
|
||||
msgstr "%sのイメージ"
|
||||
msgstr "%sの画像"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:34
|
||||
msgctxt "widget"
|
||||
@@ -889,7 +886,7 @@ msgstr "%(rate)s% %(taxname)s込"
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:35
|
||||
msgctxt "widget"
|
||||
msgid "plus %(rate)s% %(taxname)s"
|
||||
msgstr "%(rate)s% %(taxname)s抜"
|
||||
msgstr "別途%(rate)s% %(taxname)s"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:36
|
||||
msgctxt "widget"
|
||||
@@ -899,13 +896,13 @@ msgstr "税込"
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:37
|
||||
msgctxt "widget"
|
||||
msgid "plus taxes"
|
||||
msgstr "税抜"
|
||||
msgstr "税別"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:38
|
||||
#, javascript-format
|
||||
msgctxt "widget"
|
||||
msgid "currently available: %s"
|
||||
msgstr "現在%s使用可能"
|
||||
msgstr "現在の残数: %s"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:39
|
||||
msgctxt "widget"
|
||||
@@ -921,7 +918,7 @@ msgstr "提供開始前"
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:41
|
||||
msgctxt "widget"
|
||||
msgid "Not available anymore"
|
||||
msgstr "今後の提供不可"
|
||||
msgstr "提供終了"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:42
|
||||
msgctxt "widget"
|
||||
@@ -937,7 +934,7 @@ msgstr "最小注文数量:%s"
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:45
|
||||
msgctxt "widget"
|
||||
msgid "Close ticket shop"
|
||||
msgstr "チケットショップ閉店"
|
||||
msgstr "チケットショップを閉じる"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:46
|
||||
msgctxt "widget"
|
||||
@@ -950,8 +947,8 @@ msgid ""
|
||||
"There are currently a lot of users in this ticket shop. Please open the shop "
|
||||
"in a new tab to continue."
|
||||
msgstr ""
|
||||
"現在チケットショップが混み合っています。新しいタブでチケットショップを開き続"
|
||||
"行してください。"
|
||||
"現在チケットショップが混み合っています。新しいタブでチケットショップを開いて"
|
||||
"続行してください。"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:49
|
||||
msgctxt "widget"
|
||||
@@ -975,7 +972,7 @@ msgid ""
|
||||
"this ticket shop. Please click \"Continue\" to retry in a new tab."
|
||||
msgstr ""
|
||||
"現在チケットショップが混雑しているため、お客様のカートを作ることができません"
|
||||
"でした。新しいタブを開き「次へ」をクリックしてください。"
|
||||
"でした。\"続ける\"をクリックして、新しいタブで再試行してください。"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:54
|
||||
msgctxt "widget"
|
||||
@@ -988,8 +985,8 @@ msgid ""
|
||||
"You currently have an active cart for this event. If you select more "
|
||||
"products, they will be added to your existing cart."
|
||||
msgstr ""
|
||||
"お客様のカートはイベントの申し込みに有効です。商品を選択し、カートへ追加して"
|
||||
"ください。"
|
||||
"このイベントのカートに商品が入っています。商品を追加すると、既存のカートに追"
|
||||
"加されます。"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:57
|
||||
msgctxt "widget"
|
||||
@@ -1079,7 +1076,7 @@ msgstr "前週"
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:74
|
||||
msgctxt "widget"
|
||||
msgid "Open seat selection"
|
||||
msgstr "座席一覧を開く"
|
||||
msgstr "座席選択を開く"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:75
|
||||
msgctxt "widget"
|
||||
|
||||
@@ -8,16 +8,16 @@ msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-01-26 13:19+0000\n"
|
||||
"PO-Revision-Date: 2025-12-03 23:00+0000\n"
|
||||
"Last-Translator: SJang1 <git@sjang.dev>\n"
|
||||
"Language-Team: Korean <https://translate.pretix.eu/projects/pretix/pretix/ko/"
|
||||
">\n"
|
||||
"PO-Revision-Date: 2026-02-01 21:00+0000\n"
|
||||
"Last-Translator: z3rrry <z3rrry@gmail.com>\n"
|
||||
"Language-Team: Korean <https://translate.pretix.eu/projects/pretix/pretix/"
|
||||
"ko/>\n"
|
||||
"Language: ko\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.14.3\n"
|
||||
"X-Generator: Weblate 5.15.2\n"
|
||||
|
||||
#: pretix/_base_settings.py:87
|
||||
msgid "English"
|
||||
@@ -2283,6 +2283,9 @@ msgid ""
|
||||
"contain at least one position of this product. The order totals etc. still "
|
||||
"include all products contained in the order."
|
||||
msgstr ""
|
||||
"아무것도 선택하지 않으면, 모든 상품이 포함됩니다. 상품이 1개 이상 포함되는 "
|
||||
"경우에 주문이 포함됩니다. 주문 합계 등에는 주문에 포함된 모든 상품이 "
|
||||
"포함됩니다."
|
||||
|
||||
#: pretix/base/exporters/orderlist.py:283
|
||||
#: pretix/base/exporters/orderlist.py:478
|
||||
@@ -2546,10 +2549,8 @@ msgid "Voucher"
|
||||
msgstr "바우처"
|
||||
|
||||
#: pretix/base/exporters/orderlist.py:653
|
||||
#, fuzzy
|
||||
#| msgid "Voucher deleted"
|
||||
msgid "Voucher budget usage"
|
||||
msgstr "바우처 제거됨"
|
||||
msgstr "바우처 예산 사용량"
|
||||
|
||||
#: pretix/base/exporters/orderlist.py:654
|
||||
msgid "Pseudonymization ID"
|
||||
@@ -26784,11 +26785,11 @@ msgstr ""
|
||||
|
||||
#: pretix/control/views/dashboards.py:114
|
||||
msgid "Attendees (ordered)"
|
||||
msgstr ""
|
||||
msgstr "참가자 (정렬된)"
|
||||
|
||||
#: pretix/control/views/dashboards.py:124
|
||||
msgid "Attendees (paid)"
|
||||
msgstr ""
|
||||
msgstr "참가자 (결제된)"
|
||||
|
||||
#: pretix/control/views/dashboards.py:136
|
||||
#, python-brace-format
|
||||
|
||||
@@ -8,8 +8,8 @@ msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-01-26 09:10+0000\n"
|
||||
"PO-Revision-Date: 2025-11-18 17:00+0000\n"
|
||||
"Last-Translator: Hijiri Umemoto <hijiri@umemoto.org>\n"
|
||||
"PO-Revision-Date: 2026-02-01 21:00+0000\n"
|
||||
"Last-Translator: z3rrry <z3rrry@gmail.com>\n"
|
||||
"Language-Team: Korean <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||
"ko/>\n"
|
||||
"Language: ko\n"
|
||||
@@ -17,7 +17,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
"X-Generator: Weblate 5.14.3\n"
|
||||
"X-Generator: Weblate 5.15.2\n"
|
||||
|
||||
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
|
||||
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
|
||||
@@ -175,12 +175,12 @@ msgstr "유료 주문"
|
||||
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:27
|
||||
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:39
|
||||
msgid "Attendees (ordered)"
|
||||
msgstr ""
|
||||
msgstr "참가자 (정렬된)"
|
||||
|
||||
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:27
|
||||
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:39
|
||||
msgid "Attendees (paid)"
|
||||
msgstr ""
|
||||
msgstr "참가자 (결제된)"
|
||||
|
||||
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:51
|
||||
msgid "Total revenue"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgstr ""
|
||||
"Project-Id-Version: 1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-01-26 09:10+0000\n"
|
||||
"PO-Revision-Date: 2026-01-28 00:00+0000\n"
|
||||
"PO-Revision-Date: 2026-02-05 23:00+0000\n"
|
||||
"Last-Translator: Ruud Hendrickx <ruud@leckxicon.eu>\n"
|
||||
"Language-Team: Dutch <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||
"nl/>\n"
|
||||
@@ -55,7 +55,7 @@ msgstr "Kredietkaart"
|
||||
|
||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:40
|
||||
msgid "PayPal Pay Later"
|
||||
msgstr "PayPal Pay Later"
|
||||
msgstr "PayPal - Later betalen"
|
||||
|
||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:41
|
||||
msgid "iDEAL"
|
||||
@@ -186,15 +186,15 @@ msgstr "Verbinding maken met uw bank …"
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:30
|
||||
msgid "Select a check-in list"
|
||||
msgstr "Kies een inchecklijst"
|
||||
msgstr "Kies een check-in-lijst"
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:31
|
||||
msgid "No active check-in lists found."
|
||||
msgstr "Geen actieve check-inlijsten gevonden."
|
||||
msgstr "Geen actieve check-in-lijsten gevonden."
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:32
|
||||
msgid "Switch check-in list"
|
||||
msgstr "Andere inchecklijst kiezen"
|
||||
msgstr "Andere check-in-lijst kiezen"
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:33
|
||||
msgid "Search results"
|
||||
@@ -251,7 +251,7 @@ msgstr "Bevestigd"
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:47
|
||||
msgid "Approval pending"
|
||||
msgstr "Goedkeuring in afwachting"
|
||||
msgstr "Goedkeuring in behandeling"
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:48
|
||||
msgid "Redeemed"
|
||||
@@ -336,7 +336,7 @@ msgstr "Geldige tickets"
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:70
|
||||
msgid "Currently inside"
|
||||
msgstr "Op dit moment binnen"
|
||||
msgstr "Nu binnen"
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:71
|
||||
#: pretix/static/pretixcontrol/js/ui/question.js:136
|
||||
@@ -406,8 +406,8 @@ msgstr "De aanvraag duurde te lang. Probeer het opnieuw."
|
||||
msgid ""
|
||||
"We currently cannot reach the server. Please try again. Error code: {code}"
|
||||
msgstr ""
|
||||
"De server is op dit moment niet bereikbaar. Probeer het alstublieft opnieuw. "
|
||||
"Foutcode: {code}"
|
||||
"De server is op dit moment niet bereikbaar. Probeer het opnieuw. Foutcode: "
|
||||
"{code}"
|
||||
|
||||
#: pretix/static/pretixbase/js/asynctask.js:216
|
||||
msgid "We are processing your request …"
|
||||
@@ -602,11 +602,11 @@ msgstr "Tekstvak"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:913
|
||||
msgid "Barcode area"
|
||||
msgstr "Barcode gebied"
|
||||
msgstr "Ruimte voor streepjescode"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:915
|
||||
msgid "Image area"
|
||||
msgstr "Afbeeldingsgebied"
|
||||
msgstr "Ruimte voor afbeelding"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:917
|
||||
msgid "Powered by pretix"
|
||||
@@ -664,8 +664,8 @@ msgid ""
|
||||
"Your color has insufficient contrast to white. Accessibility of your site "
|
||||
"will be impacted."
|
||||
msgstr ""
|
||||
"Uw kleur heeft te weinig contrast met wit. De toegankelijkheid van uw site "
|
||||
"wordt negatief beïnvloed."
|
||||
"Uw kleur heeft onvoldoende contrast met wit. Dit heeft invloed op de "
|
||||
"toegankelijkheid van uw website."
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:443
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:463
|
||||
@@ -736,7 +736,7 @@ msgstr ""
|
||||
|
||||
#: pretix/static/pretixpresale/js/ui/cart.js:49
|
||||
msgid "Cart expired"
|
||||
msgstr "Winkelwagen is verlopen"
|
||||
msgstr "Winkelwagen verlopen"
|
||||
|
||||
#: pretix/static/pretixpresale/js/ui/cart.js:58
|
||||
#: pretix/static/pretixpresale/js/ui/cart.js:84
|
||||
@@ -936,12 +936,12 @@ msgstr "Momenteel niet beschikbaar"
|
||||
#, javascript-format
|
||||
msgctxt "widget"
|
||||
msgid "minimum amount to order: %s"
|
||||
msgstr "minimale hoeveelheid om te bestellen: %s"
|
||||
msgstr "minimale bestelhoeveelheid: %s"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:45
|
||||
msgctxt "widget"
|
||||
msgid "Close ticket shop"
|
||||
msgstr "Sluit ticketverkoop"
|
||||
msgstr "Sluit ticketwinkel"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:46
|
||||
msgctxt "widget"
|
||||
@@ -1160,51 +1160,51 @@ msgstr "zondag"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:94
|
||||
msgid "January"
|
||||
msgstr "Januari"
|
||||
msgstr "januari"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:95
|
||||
msgid "February"
|
||||
msgstr "Februari"
|
||||
msgstr "februari"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:96
|
||||
msgid "March"
|
||||
msgstr "Maart"
|
||||
msgstr "maart"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:97
|
||||
msgid "April"
|
||||
msgstr "April"
|
||||
msgstr "april"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:98
|
||||
msgid "May"
|
||||
msgstr "Mei"
|
||||
msgstr "mei"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:99
|
||||
msgid "June"
|
||||
msgstr "Juni"
|
||||
msgstr "juni"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:100
|
||||
msgid "July"
|
||||
msgstr "Juli"
|
||||
msgstr "juli"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:101
|
||||
msgid "August"
|
||||
msgstr "Augustus"
|
||||
msgstr "augustus"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:102
|
||||
msgid "September"
|
||||
msgstr "September"
|
||||
msgstr "september"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:103
|
||||
msgid "October"
|
||||
msgstr "Oktober"
|
||||
msgstr "oktober"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:104
|
||||
msgid "November"
|
||||
msgstr "November"
|
||||
msgstr "november"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:105
|
||||
msgid "December"
|
||||
msgstr "December"
|
||||
msgstr "december"
|
||||
|
||||
#~ msgid "Time zone:"
|
||||
#~ msgstr "Tijdzone:"
|
||||
|
||||
32986
src/pretix/locale/nl_BE/LC_MESSAGES/django.po
Normal file
32986
src/pretix/locale/nl_BE/LC_MESSAGES/django.po
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -179,6 +179,7 @@ def _default_context(request):
|
||||
ctx['html_page_header'] = "".join(h for h in _html_page_header if h)
|
||||
ctx['footer'] = _footer
|
||||
ctx['site_url'] = settings.SITE_URL
|
||||
ctx['request_get_items'] = request.GET.items()
|
||||
|
||||
ctx['js_datetime_format'] = get_javascript_format_without_seconds('DATETIME_INPUT_FORMATS')
|
||||
ctx['js_date_format'] = get_javascript_format_without_seconds('DATE_INPUT_FORMATS')
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
{% endif %}
|
||||
<div id="invoice" class="profile-scope"
|
||||
data-profiles-id="addresses_json"
|
||||
data-address-information-url="{% url "js_helpers.address_form" %}?invoice=true&organizer={{ event.organizer.slug|urlencode }}&event={{ event.slug|urlencode }}">
|
||||
data-address-information-url="{% url "js_helpers.address_form" %}?invoice=true&organizer={{ event.organizer.slug|urlencode }}&event={{ event.slug|urlencode }}&locale={{ request.LANGUAGE_CODE }}">
|
||||
<div class="panel-body">
|
||||
{% if addresses_data %}
|
||||
<div class="form-group profile-select-container js-do-not-copy-answers">
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
</li>
|
||||
<li class="text-center">
|
||||
<form class="form-inline" method="get" id="monthselform" action="{% eventurl event "presale:event.index" cart_namespace=cart_namespace %}">
|
||||
{% for f, v in request.GET.items %}
|
||||
{% for f, v in request_get_items %}
|
||||
{% if f != "date" %}
|
||||
<input type="hidden" name="{{ f }}" value="{{ v }}">
|
||||
{% endif %}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
</li>
|
||||
<li class="text-center">
|
||||
<form class="form-inline" method="get" id="monthselform" action="{% eventurl event "presale:event.index" cart_namespace=cart_namespace %}">
|
||||
{% for f, v in request.GET.items %}
|
||||
{% for f, v in request_get_items %}
|
||||
{% if f != "date" %}
|
||||
<input type="hidden" name="{{ f }}" value="{{ v }}">
|
||||
{% endif %}
|
||||
|
||||
@@ -304,7 +304,7 @@
|
||||
<dt>{% trans "Phone number" %}</dt>
|
||||
<dd>{{ order.phone|phone_format }}</dd>
|
||||
{% endif %}
|
||||
{% if invoice_address_asked %}
|
||||
{% if invoice_address_asked and order.invoice_address.is_business %}
|
||||
<dt>{% trans "Company" %}</dt>
|
||||
<dd>{{ order.invoice_address.company }}</dd>
|
||||
{% endif %}
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
</h4>
|
||||
</summary>
|
||||
<div id="invoice" class="panel-collapse"
|
||||
data-address-information-url="{% url "js_helpers.address_form" %}?invoice=true&organizer={{ event.organizer.slug|urlencode }}&event={{ event.slug|urlencode }}">
|
||||
data-address-information-url="{% url "js_helpers.address_form" %}?invoice=true&organizer={{ event.organizer.slug|urlencode }}&event={{ event.slug|urlencode }}&locale={{ request.LANGUAGE_CODE }}">
|
||||
<div class="panel-body">
|
||||
{% if event.settings.invoice_address_explanation_text %}
|
||||
<div>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
{% if filter_form.fields %}
|
||||
<form class="event-list-filter-form" method="get" data-save-scrollpos>
|
||||
<input type="hidden" name="filtered" value="1">
|
||||
{% for f, v in request.GET.items %}
|
||||
{% for f, v in request_get_items %}
|
||||
{% if f not in filter_form.fields and f != "page" %}
|
||||
<input type="hidden" name="{{ f }}" value="{{ v }}">
|
||||
{% endif %}
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
</li>
|
||||
<li class="text-center">
|
||||
<form class="form-inline" method="get" id="monthselform" action="{% eventurl request.organizer "presale:organizer.index" %}">
|
||||
{% for f, v in request.GET.items %}
|
||||
{% for f, v in request_get_items %}
|
||||
{% if f != "date" %}
|
||||
<input type="hidden" name="{{ f }}" value="{{ v }}">
|
||||
{% endif %}
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
</li>
|
||||
<li class="text-center">
|
||||
<form class="form-inline" method="get" id="monthselform" action="{% eventurl request.organizer "presale:organizer.index" %}">
|
||||
{% for f, v in request.GET.items %}
|
||||
{% for f, v in request_get_items %}
|
||||
{% if f != "date" %}
|
||||
<input type="hidden" name="{{ f }}" value="{{ v }}">
|
||||
{% endif %}
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
</li>
|
||||
<li class="text-center">
|
||||
<form class="form-inline" method="get" id="monthselform" action="{% eventurl request.organizer "presale:organizer.index" %}">
|
||||
{% for f, v in request.GET.items %}
|
||||
{% for f, v in request_get_items %}
|
||||
{% if f != "date" %}
|
||||
<input type="hidden" name="{{ f }}" value="{{ v }}">
|
||||
{% endif %}
|
||||
|
||||
@@ -286,6 +286,7 @@ class SetPasswordView(FormView):
|
||||
self.customer.is_verified = True
|
||||
self.customer.save()
|
||||
self.customer.log_action('pretix.customer.password.set', {})
|
||||
self.customer.send_security_notice(_("Your password has been changed."))
|
||||
messages.success(
|
||||
self.request,
|
||||
_('Your new password has been set! You can now use it to log in.'),
|
||||
@@ -541,6 +542,7 @@ class ChangePasswordView(CustomerAccountBaseMixin, FormView):
|
||||
customer.set_password(form.cleaned_data['password'])
|
||||
customer.save()
|
||||
messages.success(self.request, _('Your changes have been saved.'))
|
||||
customer.send_security_notice(_("Your password has been changed."))
|
||||
update_customer_session_auth_hash(self.request, customer)
|
||||
return HttpResponseRedirect(self.get_success_url())
|
||||
|
||||
@@ -631,11 +633,15 @@ class ConfirmChangeView(View):
|
||||
|
||||
try:
|
||||
with transaction.atomic():
|
||||
old_email = customer.email
|
||||
customer.email = data['email']
|
||||
customer.save()
|
||||
customer.log_action('pretix.customer.changed', {
|
||||
'email': data['email']
|
||||
})
|
||||
msg = _('Your email address has been changed from {old_email} to {email}.').format(old_email=old_email, email=customer.email)
|
||||
customer.send_security_notice(msg, email=old_email)
|
||||
customer.send_security_notice(msg, email=customer.email)
|
||||
except IntegrityError:
|
||||
messages.success(request, _('Your email address has not been updated since the address is already in use '
|
||||
'for another customer account.'))
|
||||
|
||||
@@ -49,7 +49,7 @@ from django.views.decorators.cache import cache_page
|
||||
from django.views.decorators.gzip import gzip_page
|
||||
from django.views.decorators.http import condition
|
||||
from django.views.i18n import (
|
||||
JavaScriptCatalog, builtin_template_path, get_formats,
|
||||
JavaScriptCatalog, get_formats, js_catalog_template,
|
||||
)
|
||||
from lxml import html
|
||||
|
||||
@@ -170,8 +170,7 @@ def generate_widget_js(version, lang):
|
||||
'September', 'October', 'November', 'December'
|
||||
)
|
||||
catalog = dict((k, v) for k, v in catalog.items() if k.startswith('widget\u0004') or k in str_wl)
|
||||
with builtin_template_path("i18n_catalog.js").open(encoding="utf-8") as fh:
|
||||
template = Engine().from_string(fh.read())
|
||||
template = Engine().from_string(js_catalog_template)
|
||||
context = Context({
|
||||
'catalog_str': indent(json.dumps(
|
||||
catalog, sort_keys=True, indent=2)) if catalog else None,
|
||||
|
||||
@@ -530,7 +530,6 @@ X_FRAME_OPTIONS = 'DENY'
|
||||
|
||||
# URL settings
|
||||
ROOT_URLCONF = 'pretix.multidomain.maindomain_urlconf'
|
||||
FORMS_URLFIELD_ASSUME_HTTPS = True # transitional for django 6.0
|
||||
|
||||
WSGI_APPLICATION = 'pretix.wsgi.application'
|
||||
|
||||
|
||||
@@ -252,7 +252,7 @@ Vue.component('availbox', {
|
||||
variation: Object
|
||||
},
|
||||
mounted: function() {
|
||||
if (this.$root.itemnum === 1 && (!this.$root.categories[0].items[0].has_variations || this.$root.categories[0].items[0].variations.length < 2) && !this.$root.has_seating_plan ? 1 : 0) {
|
||||
if (!this.$root.cart_exists && this.$root.itemnum === 1 && (!this.$root.categories[0].items[0].has_variations || this.$root.categories[0].items[0].variations.length < 2) && !this.$root.has_seating_plan ? 1 : 0) {
|
||||
this.$refs.quantity.value = 1;
|
||||
if (this.order_max === 1) {
|
||||
this.$refs.quantity.checked = true;
|
||||
|
||||
@@ -23,7 +23,9 @@ filterwarnings =
|
||||
error
|
||||
ignore:.*invalid escape sequence.*:
|
||||
ignore:The 'warn' method is deprecated:DeprecationWarning
|
||||
ignore::django.utils.deprecation.RemovedInDjango60Warning:
|
||||
ignore::django.utils.deprecation.RemovedInDjango51Warning:django.core.files.storage
|
||||
ignore:.*index_together.*:django.utils.deprecation.RemovedInDjango51Warning:
|
||||
ignore:.*get_storage_class.*:django.utils.deprecation.RemovedInDjango51Warning:compressor
|
||||
ignore:.*This signal will soon be only available for plugins that declare to be organizer-level.*:DeprecationWarning:
|
||||
ignore::DeprecationWarning:mt940
|
||||
ignore::DeprecationWarning:cbor2
|
||||
|
||||
@@ -32,21 +32,26 @@
|
||||
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations under the License.
|
||||
|
||||
import datetime
|
||||
import os
|
||||
import re
|
||||
from decimal import Decimal
|
||||
from email.mime.text import MIMEText
|
||||
|
||||
import pytest
|
||||
from django.conf import settings
|
||||
from django.core import mail as djmail
|
||||
from django.test import override_settings
|
||||
from django.utils.html import escape
|
||||
from django.utils.timezone import now
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django_scopes import scope
|
||||
from django_scopes import scope, scopes_disabled
|
||||
from i18nfield.strings import LazyI18nString
|
||||
|
||||
from pretix.base.email import get_email_context
|
||||
from pretix.base.models import Event, Organizer, OutgoingMail, User
|
||||
from pretix.base.models import (
|
||||
Event, InvoiceAddress, Order, Organizer, OutgoingMail, User,
|
||||
)
|
||||
from pretix.base.services.mail import mail, mail_send_task
|
||||
|
||||
|
||||
@@ -68,6 +73,45 @@ def env():
|
||||
yield event, user, o
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@scopes_disabled()
|
||||
def item(env):
|
||||
return env[0].items.create(name="Budget Ticket", default_price=23)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@scopes_disabled()
|
||||
def order(env, item):
|
||||
event, _, _ = env
|
||||
o = Order.objects.create(
|
||||
code="FOO",
|
||||
event=event,
|
||||
email="dummy@dummy.test",
|
||||
status=Order.STATUS_PENDING,
|
||||
secret="k24fiuwvu8kxz3y1",
|
||||
sales_channel=event.organizer.sales_channels.get(identifier="web"),
|
||||
datetime=datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=datetime.timezone.utc),
|
||||
expires=datetime.datetime(2017, 12, 10, 10, 0, 0, tzinfo=datetime.timezone.utc),
|
||||
total=23,
|
||||
locale="en",
|
||||
)
|
||||
o.positions.create(
|
||||
order=o,
|
||||
item=item,
|
||||
variation=None,
|
||||
price=Decimal("23"),
|
||||
attendee_email="peter@example.org",
|
||||
attendee_name_parts={"given_name": "Peter", "family_name": "Miller"},
|
||||
secret="z3fsn8jyufm5kpk768q69gkbyr5f4h6w",
|
||||
pseudonymization_id="ABCDEFGHKL",
|
||||
)
|
||||
InvoiceAddress.objects.create(
|
||||
order=o,
|
||||
name_parts={"given_name": "Peter", "family_name": "Miller"},
|
||||
)
|
||||
return o
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_send_mail_with_prefix(env):
|
||||
djmail.outbox = []
|
||||
@@ -279,7 +323,7 @@ def _extract_html(mail):
|
||||
def test_placeholder_html_rendering_from_template(env):
|
||||
djmail.outbox = []
|
||||
event, user, organizer = env
|
||||
event.name = "<strong>event & co. kg</strong>"
|
||||
event.name = "<strong>event & co. kg</strong> {currency}"
|
||||
event.save()
|
||||
mail('dummy@dummy.dummy', '{event} Test subject', 'mailtest.txt', get_email_context(
|
||||
event=event,
|
||||
@@ -288,25 +332,26 @@ def test_placeholder_html_rendering_from_template(env):
|
||||
|
||||
assert len(djmail.outbox) == 1
|
||||
assert djmail.outbox[0].to == [user.email]
|
||||
assert 'Event name: <strong>event & co. kg</strong>' in djmail.outbox[0].body
|
||||
assert '**IBAN**: 123 \n**BIC**: 456' in djmail.outbox[0].body
|
||||
assert '**Meta**: *Beep*' in djmail.outbox[0].body
|
||||
assert 'Event website: [<strong>event & co. kg</strong>](https://example.org/dummy)' in djmail.outbox[0].body
|
||||
assert 'Other website: [<strong>event & co. kg</strong>](https://example.com)' in djmail.outbox[0].body
|
||||
assert '<' not in djmail.outbox[0].body
|
||||
assert '&' not in djmail.outbox[0].body
|
||||
# Known bug for now: These should not have HTML for the plain body, but we'll fix this safter the security release
|
||||
assert escape('Event name: <strong>event & co. kg</strong> {currency}') in djmail.outbox[0].body
|
||||
assert '<strong>IBAN</strong>: 123<br>\n<strong>BIC</strong>: 456' in djmail.outbox[0].body
|
||||
assert '**Meta**: <em>Beep</em>' in djmail.outbox[0].body
|
||||
assert escape('Event website: [<strong>event & co. kg</strong> {currency}](https://example.org/dummy)') in djmail.outbox[0].body
|
||||
# todo: assert '<' not in djmail.outbox[0].body
|
||||
# todo: assert '&' not in djmail.outbox[0].body
|
||||
assert 'Unevaluated placeholder: {currency}' in djmail.outbox[0].body
|
||||
assert 'EUR' not in djmail.outbox[0].body
|
||||
html = _extract_html(djmail.outbox[0])
|
||||
|
||||
assert '<strong>event' not in html
|
||||
assert 'Event name: <strong>event & co. kg</strong>' in html
|
||||
assert 'Event name: <strong>event & co. kg</strong> {currency}' in html
|
||||
assert '<strong>IBAN</strong>: 123<br/>\n<strong>BIC</strong>: 456' in html
|
||||
assert '<strong>Meta</strong>: <em>Beep</em>' in html
|
||||
assert 'Unevaluated placeholder: {currency}' in html
|
||||
assert 'EUR' not in html
|
||||
assert re.search(
|
||||
r'Event website: <a href="https://example.org/dummy" rel="noopener" style="[^"]+" target="_blank"><strong>event & co. kg</strong></a>',
|
||||
html
|
||||
)
|
||||
assert re.search(
|
||||
r'Other website: <a href="https://example.com" rel="noopener" style="[^"]+" target="_blank"><strong>event & co. kg</strong></a>',
|
||||
r'Event website: <a href="https://example.org/dummy" rel="noopener" style="[^"]+" target="_blank">'
|
||||
r'<strong>event & co. kg</strong> {currency}</a>',
|
||||
html
|
||||
)
|
||||
|
||||
@@ -324,7 +369,7 @@ def test_placeholder_html_rendering_from_string(env):
|
||||
})
|
||||
djmail.outbox = []
|
||||
event, user, organizer = env
|
||||
event.name = "<strong>event & co. kg</strong>"
|
||||
event.name = "<strong>event & co. kg</strong> {currency}"
|
||||
event.save()
|
||||
ctx = get_email_context(
|
||||
event=event,
|
||||
@@ -335,9 +380,9 @@ def test_placeholder_html_rendering_from_string(env):
|
||||
|
||||
assert len(djmail.outbox) == 1
|
||||
assert djmail.outbox[0].to == [user.email]
|
||||
assert 'Event name: <strong>event & co. kg</strong>' in djmail.outbox[0].body
|
||||
assert 'Event website: [<strong>event & co. kg</strong>](https://example.org/dummy)' in djmail.outbox[0].body
|
||||
assert 'Other website: [<strong>event & co. kg</strong>](https://example.com)' in djmail.outbox[0].body
|
||||
assert 'Event name: <strong>event & co. kg</strong> {currency}' in djmail.outbox[0].body
|
||||
assert 'Event website: [<strong>event & co. kg</strong> {currency}](https://example.org/dummy)' in djmail.outbox[0].body
|
||||
assert 'Other website: [<strong>event & co. kg</strong> {currency}](https://example.com)' in djmail.outbox[0].body
|
||||
assert '**IBAN**: 123 \n**BIC**: 456' in djmail.outbox[0].body
|
||||
assert '**Meta**: *Beep*' in djmail.outbox[0].body
|
||||
assert 'URL: https://google.com' in djmail.outbox[0].body
|
||||
@@ -352,11 +397,13 @@ def test_placeholder_html_rendering_from_string(env):
|
||||
assert '<strong>IBAN</strong>: 123<br/>\n<strong>BIC</strong>: 456' in html
|
||||
assert '<strong>Meta</strong>: <em>Beep</em>' in html
|
||||
assert re.search(
|
||||
r'Event website: <a href="https://example.org/dummy" rel="noopener" style="[^"]+" target="_blank"><strong>event & co. kg</strong></a>',
|
||||
r'Event website: <a href="https://example.org/dummy" rel="noopener" style="[^"]+" target="_blank">'
|
||||
r'<strong>event & co. kg</strong> {currency}</a>',
|
||||
html
|
||||
)
|
||||
assert re.search(
|
||||
r'Other website: <a href="https://example.com" rel="noopener" style="[^"]+" target="_blank"><strong>event & co. kg</strong></a>',
|
||||
r'Other website: <a href="https://example.com" rel="noopener" style="[^"]+" target="_blank">'
|
||||
r'<strong>event & co. kg</strong> {currency}</a>',
|
||||
html
|
||||
)
|
||||
assert re.search(
|
||||
@@ -377,3 +424,141 @@ def test_placeholder_html_rendering_from_string(env):
|
||||
r'style="[^"]+" target="_blank">Link & Text</a>',
|
||||
html
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_nested_placeholder_inclusion_full_process(env, order):
|
||||
# Test that it is not possible to sneak in a placeholder like {url_cancel} inside a user-controlled
|
||||
# placeholder value like {invoice_company}
|
||||
event, user, organizer = env
|
||||
position = order.positions.get()
|
||||
order.invoice_address.company = "{url_cancel} Corp"
|
||||
order.invoice_address.save()
|
||||
event.settings.mail_text_resend_link = LazyI18nString({"en": "Ticket for {invoice_company}"})
|
||||
event.settings.mail_subject_resend_link_attendee = LazyI18nString({"en": "Ticket for {invoice_company}"})
|
||||
|
||||
djmail.outbox = []
|
||||
position.resend_link()
|
||||
assert len(djmail.outbox) == 1
|
||||
assert djmail.outbox[0].to == [position.attendee_email]
|
||||
assert "Ticket for {url_cancel} Corp" == djmail.outbox[0].subject
|
||||
assert "/cancel" not in djmail.outbox[0].body
|
||||
assert "/order" not in djmail.outbox[0].body
|
||||
html, plain = _extract_html(djmail.outbox[0]), djmail.outbox[0].body
|
||||
for part in (html, plain):
|
||||
assert "Ticket for {url_cancel} Corp" in part
|
||||
assert "/order/" not in part
|
||||
assert "/cancel" not in part
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_nested_placeholder_inclusion_mail_service(env):
|
||||
# test that it is not possible to have placeholders within the values of placeholders when
|
||||
# the mail() function is called directly
|
||||
template = LazyI18nString("Event name: {event}")
|
||||
djmail.outbox = []
|
||||
event, user, organizer = env
|
||||
event.name = "event & {currency} co. kg"
|
||||
event.slug = "event-co-ag-slug"
|
||||
event.save()
|
||||
|
||||
mail(
|
||||
"dummy@dummy.dummy",
|
||||
"{event} Test subject",
|
||||
template,
|
||||
get_email_context(
|
||||
event=event,
|
||||
payment_info="**IBAN**: 123 \n**BIC**: 456 {event}",
|
||||
),
|
||||
event,
|
||||
)
|
||||
|
||||
assert len(djmail.outbox) == 1
|
||||
assert djmail.outbox[0].to == [user.email]
|
||||
html, plain = _extract_html(djmail.outbox[0]), djmail.outbox[0].body
|
||||
for part in (html, plain, djmail.outbox[0].subject):
|
||||
assert "event & {currency} co. kg" in part or "event & {currency} co. kg" in part
|
||||
assert "EUR" not in part
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
@pytest.mark.parametrize("tpl", [
|
||||
"Event: {event.__class__}",
|
||||
"Event: {{event.__class__}}",
|
||||
"Event: {{{event.__class__}}}",
|
||||
])
|
||||
def test_variable_inclusion_from_string_full_process(env, tpl, order):
|
||||
# Test that it is not possible to use placeholders that leak system information in templates
|
||||
# when run through system processes
|
||||
event, user, organizer = env
|
||||
event.name = "event & co. kg"
|
||||
event.save()
|
||||
position = order.positions.get()
|
||||
event.settings.mail_text_resend_link = LazyI18nString({"en": tpl})
|
||||
event.settings.mail_subject_resend_link_attendee = LazyI18nString({"en": tpl})
|
||||
|
||||
position.resend_link()
|
||||
assert len(djmail.outbox) == 1
|
||||
html, plain = _extract_html(djmail.outbox[0]), djmail.outbox[0].body
|
||||
for part in (html, plain, djmail.outbox[0].subject):
|
||||
assert "{event.__class__}" in part
|
||||
assert "LazyI18nString" not in part
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
@pytest.mark.parametrize("tpl", [
|
||||
"Event: {event.__class__}",
|
||||
"Event: {{event.__class__}}",
|
||||
"Event: {{{event.__class__}}}",
|
||||
])
|
||||
def test_variable_inclusion_from_string_mail_service(env, tpl):
|
||||
# Test that it is not possible to use placeholders that leak system information in templates
|
||||
# when run through mail() directly
|
||||
event, user, organizer = env
|
||||
event.name = "event & co. kg"
|
||||
event.save()
|
||||
|
||||
djmail.outbox = []
|
||||
mail(
|
||||
"dummy@dummy.dummy",
|
||||
tpl,
|
||||
LazyI18nString(tpl),
|
||||
get_email_context(
|
||||
event=event,
|
||||
payment_info="**IBAN**: 123 \n**BIC**: 456\n" + tpl,
|
||||
),
|
||||
event,
|
||||
)
|
||||
assert len(djmail.outbox) == 1
|
||||
html, plain = _extract_html(djmail.outbox[0]), djmail.outbox[0].body
|
||||
for part in (html, plain, djmail.outbox[0].subject):
|
||||
assert "{event.__class__}" in part
|
||||
assert "LazyI18nString" not in part
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_escaped_braces_mail_services(env):
|
||||
# Test that braces can be escaped by doubling
|
||||
template = LazyI18nString("Event name: -{{currency}}-")
|
||||
djmail.outbox = []
|
||||
event, user, organizer = env
|
||||
event.name = "event & co. kg"
|
||||
event.save()
|
||||
|
||||
mail(
|
||||
"dummy@dummy.dummy",
|
||||
"-{{currency}}- Test subject",
|
||||
template,
|
||||
get_email_context(
|
||||
event=event,
|
||||
payment_info="**IBAN**: 123 \n**BIC**: 456 {event}",
|
||||
),
|
||||
event,
|
||||
)
|
||||
|
||||
assert len(djmail.outbox) == 1
|
||||
assert djmail.outbox[0].to == [user.email]
|
||||
html, plain = _extract_html(djmail.outbox[0]), djmail.outbox[0].body
|
||||
for part in (html, plain, djmail.outbox[0].subject):
|
||||
assert "EUR" not in part
|
||||
assert "-{currency}-" in part
|
||||
|
||||
@@ -29,6 +29,8 @@ def test_format_map():
|
||||
assert format_map("Foo {baz}", {"bar": 3}) == "Foo {baz}"
|
||||
assert format_map("Foo {bar.__module__}", {"bar": 3}) == "Foo {bar.__module__}"
|
||||
assert format_map("Foo {bar!s}", {"bar": 3}) == "Foo 3"
|
||||
assert format_map("Foo {bar!r}", {"bar": '3'}) == "Foo 3"
|
||||
assert format_map("Foo {bar!a}", {"bar": '3'}) == "Foo 3"
|
||||
assert format_map("Foo {bar:<20}", {"bar": 3}) == "Foo 3"
|
||||
|
||||
|
||||
|
||||
@@ -164,6 +164,7 @@ def test_org_resetpw(env, client):
|
||||
customer.refresh_from_db()
|
||||
assert customer.check_password('PANioMR62')
|
||||
assert customer.is_verified
|
||||
assert len(djmail.outbox) == 2
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
@@ -623,6 +624,7 @@ def test_change_email(env, client):
|
||||
customer.refresh_from_db()
|
||||
assert customer.email == 'john@example.org'
|
||||
assert len(djmail.outbox) == 1
|
||||
assert djmail.outbox[0].to == ['john@example.com']
|
||||
|
||||
token = dumps({
|
||||
'customer': customer.pk,
|
||||
@@ -632,6 +634,9 @@ def test_change_email(env, client):
|
||||
assert r.status_code == 302
|
||||
customer.refresh_from_db()
|
||||
assert customer.email == 'john@example.com'
|
||||
assert len(djmail.outbox) == 3
|
||||
assert djmail.outbox[1].to == ['john@example.org']
|
||||
assert djmail.outbox[2].to == ['john@example.com']
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
@@ -673,6 +678,7 @@ def test_change_pw(env, client, client2):
|
||||
|
||||
r = client.get('/bigevents/account/password')
|
||||
assert r.status_code == 200
|
||||
assert len(djmail.outbox) == 1
|
||||
|
||||
# Client 2 got logged out
|
||||
r = client2.post('/bigevents/account/password')
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{% load i18n %}
|
||||
This is a test file for sending mails.
|
||||
Event name: {event}
|
||||
Event name: {{ event }}
|
||||
Unevaluated placeholder: {currency}
|
||||
{% get_current_language as LANGUAGE_CODE %}
|
||||
The language code used for rendering this email is {{ LANGUAGE_CODE }}.
|
||||
|
||||
Payment info:
|
||||
{payment_info}
|
||||
{{ payment_info }}
|
||||
|
||||
**Meta**: {meta_Test}
|
||||
**Meta**: {{ meta_Test }}
|
||||
|
||||
Event website: [{event}](https://example.org/{event_slug})
|
||||
Other website: [{event}]({meta_Website})
|
||||
Event website: [{{event}}](https://example.org/{{event_slug}})
|
||||
Reference in New Issue
Block a user