Compare commits

..

1 Commits

Author SHA1 Message Date
Raphael Michel
6ad1380632 Fix context processor crash on "event not found" page (PRETIXEU-BAS) 2025-03-17 09:32:14 +01:00
63 changed files with 3046 additions and 4112 deletions

View File

@@ -91,7 +91,7 @@ dependencies = [
"redis==5.2.*",
"reportlab==4.3.*",
"requests==2.31.*",
"sentry-sdk==2.23.*",
"sentry-sdk==2.22.*",
"sepaxml==2.6.*",
"stripe==7.9.*",
"text-unidecode==1.*",

View File

@@ -176,7 +176,7 @@ class BaseCartPositionCreateSerializer(I18nAwareModelSerializer):
def create(self, validated_data):
validated_data.pop('_quotas')
answers_data = validated_data.pop('answers', [])
answers_data = validated_data.pop('answers')
attendee_name = validated_data.pop('attendee_name', '')
if attendee_name and not validated_data.get('attendee_name_parts'):

View File

@@ -165,7 +165,6 @@ class CheckinListViewSet(viewsets.ModelViewSet):
if not serializer.validated_data.get('position'):
kwargs['position'] = OrderPosition.all.filter(
order__event=self.request.event,
secret=serializer.validated_data['raw_barcode']
).first()

View File

@@ -83,8 +83,8 @@ from pretix.base.services.tax import (
VATIDFinalError, VATIDTemporaryError, validate_vat_id,
)
from pretix.base.settings import (
COUNTRIES_WITH_STATE_IN_ADDRESS, COUNTRY_STATE_LABEL,
PERSON_NAME_SALUTATIONS, PERSON_NAME_SCHEMES, PERSON_NAME_TITLE_GROUPS,
COUNTRIES_WITH_STATE_IN_ADDRESS, PERSON_NAME_SALUTATIONS,
PERSON_NAME_SCHEMES, PERSON_NAME_TITLE_GROUPS,
)
from pretix.base.templatetags.rich_text import rich_text
from pretix.base.timemachine import time_machine_now
@@ -721,7 +721,7 @@ class BaseQuestionsForm(forms.Form):
'data-country-information-url': reverse('js_helpers.states'),
}),
)
c = [('', '---')]
c = [('', pgettext_lazy('address', 'Select state'))]
fprefix = str(self.prefix) + '-' if self.prefix is not None and self.prefix != '-' else ''
cc = None
state = None
@@ -1079,7 +1079,7 @@ class BaseInvoiceAddressForm(forms.ModelForm):
self.fields['country'].choices = CachedCountries()
self.fields['country'].widget.attrs['data-country-information-url'] = reverse('js_helpers.states')
c = [('', '---')]
c = [('', pgettext_lazy('address', 'Select state'))]
fprefix = self.prefix + '-' if self.prefix else ''
cc = None
if fprefix + 'country' in self.data:
@@ -1088,19 +1088,16 @@ class BaseInvoiceAddressForm(forms.ModelForm):
cc = str(self.initial['country'])
elif self.instance and self.instance.country:
cc = str(self.instance.country)
state_label = pgettext_lazy('address', 'State')
if cc and cc in COUNTRIES_WITH_STATE_IN_ADDRESS:
types, form = COUNTRIES_WITH_STATE_IN_ADDRESS[cc]
statelist = [s for s in pycountry.subdivisions.get(country_code=cc) if s.type in types]
c += sorted([(s.code[3:], s.name) for s in statelist], key=lambda s: s[1])
if cc in COUNTRY_STATE_LABEL:
state_label = COUNTRY_STATE_LABEL[cc]
elif fprefix + 'state' in self.data:
self.data = self.data.copy()
del self.data[fprefix + 'state']
self.fields['state'] = forms.ChoiceField(
label=state_label,
label=pgettext_lazy('address', 'State'),
required=False,
choices=c,
widget=forms.Select(attrs={

View File

@@ -1,41 +0,0 @@
# Generated by Django 4.2.16 on 2025-02-28 13:25
from django.db import migrations, models
def remove_duplicates(apps, schema_editor):
UserKnownLoginSource = apps.get_model("pretixbase", "UserKnownLoginSource")
unique_fields = ["user", "agent_type", "device_type", "os_type", "country"]
duplicates = (
UserKnownLoginSource.objects
.values(*unique_fields)
.order_by()
.annotate(latest_id=models.Max('id'), count=models.Count('id'))
.filter(count__gt=1)
)
for duplicate in duplicates:
(
UserKnownLoginSource.objects
.filter(**{x: duplicate[x] for x in unique_fields})
.exclude(id=duplicate["latest_id"])
.delete()
)
class Migration(migrations.Migration):
dependencies = [
("pretixbase", "0277_customerssoclient_require_pkce_and_more"),
]
operations = [
migrations.RunPython(remove_duplicates, migrations.RunPython.noop),
migrations.AlterUniqueTogether(
name="userknownloginsource",
unique_together={
("user", "agent_type", "device_type", "os_type", "country")
},
),
]

View File

@@ -602,9 +602,6 @@ class UserKnownLoginSource(models.Model):
country = FastCountryField(null=True, blank=True)
last_seen = models.DateTimeField()
class Meta:
unique_together = ('user', 'agent_type', 'device_type', 'os_type', 'country')
class StaffSession(models.Model):
user = models.ForeignKey('User', on_delete=models.PROTECT)

View File

@@ -60,7 +60,6 @@ from django.urls import reverse
from django.utils.crypto import get_random_string
from django.utils.formats import date_format
from django.utils.functional import cached_property
from django.utils.html import format_html
from django.utils.timezone import make_aware, now
from django.utils.translation import gettext, gettext_lazy as _
from django_scopes import ScopedManager, scopes_disabled
@@ -172,7 +171,7 @@ class EventMixin:
self.date_to.astimezone(tz), ("D" if short else "l")
)
def get_date_range_display(self, tz=None, force_show_end=False, as_html=False, try_to_show_times=False) -> str:
def get_date_range_display(self, tz=None, force_show_end=False, as_html=False) -> str:
"""
Returns a formatted string containing the start date and the end date
of the event with respect to the current locale and to the ``show_date_to``
@@ -181,48 +180,36 @@ class EventMixin:
tz = tz or self.timezone
if (not self.settings.show_date_to and not force_show_end) or not self.date_to:
df, dt = self.date_from, self.date_from
show_times = try_to_show_times
else:
df, dt = self.date_from, self.date_to
show_times = try_to_show_times and self.settings.show_times and (
# Show times if start and end are on the same day ("08:00-10:00")
dt.astimezone(tz).date() == df.astimezone(tz).date() or
# Show times if start and end are on consecutive days and less than 24h ("23:00-03:00")
(dt.astimezone(tz).date() == df.astimezone(tz).date() + timedelta(days=1) and
dt.astimezone(tz).time() < df.astimezone(tz).time())
)
d = daterange(df.astimezone(tz), dt.astimezone(tz), as_html)
if show_times:
if (not self.settings.show_date_to and not force_show_end) or not self.date_to:
time_str = _date(self.date_from.astimezone(tz), "TIME_FORMAT")
else:
time_str = '{}{}'.format(
_date(self.date_from.astimezone(tz), "TIME_FORMAT"),
_date(self.date_to.astimezone(tz), "TIME_FORMAT"),
)
if as_html:
d = format_html(
d + ' <time datetime="{}" data-timezone="{}" data-time-short>{}</time>',
self.date_from.isoformat(),
str(self.timezone),
time_str,
)
else:
d = d + ' ' + time_str
return d
def get_date_range_display_with_times(self) -> str: # Helper for usage from templates
return self.get_date_range_display(try_to_show_times=True)
def get_date_range_display_with_times_as_html(self) -> str: # Helper for usage from templates
return self.get_date_range_display(try_to_show_times=True, as_html=True)
return daterange(df.astimezone(tz), dt.astimezone(tz), as_html)
def get_date_range_display_as_html(self, tz=None, force_show_end=False) -> str:
return self.get_date_range_display(tz, force_show_end, as_html=True)
def get_time_range_display(self, tz=None, force_show_end=False) -> str:
"""
Returns a formatted string containing the start time and sometimes the end time
of the event with respect to the current locale and to the ``show_date_to``
setting. Dates are not shown. This is usually used in combination with get_date_range_display
"""
tz = tz or self.timezone
show_date_to = self.date_to and (self.settings.show_date_to or force_show_end) and (
# Show date to if start and end are on the same day ("08:00-10:00")
self.date_to.astimezone(tz).date() == self.date_from.astimezone(tz).date() or
# Show date to if start and end are on consecutive days and less than 24h ("23:00-03:00")
(self.date_to.astimezone(tz).date() == self.date_from.astimezone(tz).date() + timedelta(days=1) and
self.date_to.astimezone(tz).time() < self.date_from.astimezone(tz).time())
# Do not show end time if this is a 5-day event because there's no way to make it understandable
)
if show_date_to:
return '{} {}'.format(
_date(self.date_from.astimezone(tz), "TIME_FORMAT"),
_date(self.date_to.astimezone(tz), "TIME_FORMAT"),
)
return _date(self.date_from.astimezone(tz), "TIME_FORMAT")
@property
def timezone(self):
return pytz_deprecation_shim.timezone(self.settings.timezone)

View File

@@ -1199,8 +1199,6 @@ class Order(LockModel, LoggedModel):
'invoices': [i.pk for i in invoices] if invoices else [],
'attach_tickets': attach_tickets,
'attach_ical': attach_ical,
'attach_other_files': attach_other_files,
'attach_cached_files': [cf.filename for cf in attach_cached_files] if attach_cached_files else [],
}
)
@@ -2859,8 +2857,6 @@ class OrderPosition(AbstractPosition):
'invoices': [i.pk for i in invoices] if invoices else [],
'attach_tickets': attach_tickets,
'attach_ical': attach_ical,
'attach_other_files': attach_other_files,
'attach_cached_files': [],
}
)

View File

@@ -286,8 +286,6 @@ class WaitingListEntry(LoggedModel):
'subject': subject,
'message': email_content,
'recipient': recipient,
'attach_other_files': attach_other_files,
'attach_cached_files': [cf.filename for cf in attach_cached_files] if attach_cached_files else [],
}
)

View File

@@ -3712,14 +3712,6 @@ COUNTRIES_WITH_STATE_IN_ADDRESS = {
'MY': (['State', 'Federal territory'], 'long'),
'MX': (['State', 'Federal district'], 'short'),
'US': (['State', 'Outlying area', 'District'], 'short'),
'IT': (['Province', 'Free municipal consortium', 'Metropolitan city', 'Autonomous province',
'Free municipal consortium', 'Decentralized regional entity'], 'short'),
}
COUNTRY_STATE_LABEL = {
# Countries in which the "State" field should not be called "State"
'CA': pgettext_lazy('address', 'Province'),
'JP': pgettext_lazy('address', 'Prefecture'),
'IT': pgettext_lazy('address', 'Province'),
}
settings_hierarkey = Hierarkey(attribute_name='settings')

View File

@@ -28,7 +28,7 @@
<code>Host: {{ request.headers.Host }}</code>
{% if xfh %}
<br>
<code>X-Forwarded-Host: {{ xfh }}</code>
<code>X-Forwarded-For: {{ xfh }}</code>
{% if not settings.USE_X_FORWARDED_HOST %}({% trans "ignored" %}){% endif %}
{% endif %}
</dd>

View File

@@ -15,7 +15,10 @@
{{ event.name }}
<br>
{% if event.has_subevents and ev.name|upper != event.name|upper %}{{ ev.name }}<br>{% endif %}
{{ ev.get_date_range_display_with_times }}
{{ ev.get_date_range_display }}
{% if event.settings.show_times %}
{{ ev.date_from|date:"TIME_FORMAT" }}
{% endif %}
</td>
</tr>
<tr>
@@ -104,7 +107,10 @@
{% if groupkey.2.name|upper != event.name|upper %}
{{ groupkey.2.name }} &middot;
{% endif %}
{{ groupkey.2.get_date_range_display_with_times }}
{{ groupkey.2.get_date_range_display }}
{% if event.settings.show_times %}
{{ groupkey.2.date_from|date:"TIME_FORMAT" }}
{% endif %}
{% if groupkey.2.location %}
<br>
{{ groupkey.2.location|oneline }}

View File

@@ -21,15 +21,12 @@
#
import pycountry
from django.http import JsonResponse
from django.utils.translation import pgettext
from pretix.base.addressvalidation import (
COUNTRIES_WITH_STREET_ZIPCODE_AND_CITY_REQUIRED,
)
from pretix.base.models.tax import VAT_ID_COUNTRIES
from pretix.base.settings import (
COUNTRIES_WITH_STATE_IN_ADDRESS, COUNTRY_STATE_LABEL,
)
from pretix.base.settings import COUNTRIES_WITH_STATE_IN_ADDRESS
def states(request):
@@ -38,11 +35,7 @@ def states(request):
'street': {'required': True},
'zipcode': {'required': cc in COUNTRIES_WITH_STREET_ZIPCODE_AND_CITY_REQUIRED},
'city': {'required': cc in COUNTRIES_WITH_STREET_ZIPCODE_AND_CITY_REQUIRED},
'state': {
'visible': cc in COUNTRIES_WITH_STATE_IN_ADDRESS,
'required': cc in COUNTRIES_WITH_STATE_IN_ADDRESS,
'label': COUNTRY_STATE_LABEL.get(cc, pgettext('address', 'State')),
},
'state': {'visible': cc in COUNTRIES_WITH_STATE_IN_ADDRESS, 'required': cc in COUNTRIES_WITH_STATE_IN_ADDRESS},
'vat_id': {'visible': cc in VAT_ID_COUNTRIES, 'required': False},
}
if cc not in COUNTRIES_WITH_STATE_IN_ADDRESS:

View File

@@ -43,7 +43,7 @@ from django.utils.translation import get_language
from django_scopes import scope
from pretix.base.models.auth import StaffSession
from pretix.base.settings import COUNTRY_STATE_LABEL, GlobalSettingsObject
from pretix.base.settings import GlobalSettingsObject
from pretix.control.navigation import (
get_event_navigation, get_global_navigation, get_organizer_navigation,
)
@@ -140,7 +140,6 @@ def _default_context(request):
ctx['js_time_format'] = get_javascript_format('TIME_INPUT_FORMATS')
ctx['js_locale'] = get_moment_locale()
ctx['select2locale'] = get_language()[:2]
ctx['COUNTRY_STATE_LABEL'] = COUNTRY_STATE_LABEL
ctx['warning_update_available'] = False
ctx['warning_update_check_active'] = False

View File

@@ -1475,9 +1475,7 @@ class CountriesAndEUAndStates(CountriesAndEU):
def __iter__(self):
for country_code, country_name in super().__iter__():
yield country_code, country_name
if country_code in COUNTRIES_WITH_STATE_IN_ADDRESS and country_code not in {"IT"}:
# Special case for Italy: Provinces are used in addresses, but are too low-level to
# have influence on taxes, so we avoid the bloat in the list of selectable countries.
if country_code in COUNTRIES_WITH_STATE_IN_ADDRESS:
types, form = COUNTRIES_WITH_STATE_IN_ADDRESS[country_code]
yield from sorted(((state.code, country_name + " - " + state.name)
for state in pycountry.subdivisions.get(country_code=country_code)

View File

@@ -70,7 +70,6 @@ from pretix.helpers.database import (
)
from pretix.helpers.dicts import move_to_end
from pretix.helpers.i18n import get_format_without_seconds, i18ncomp
from pretix.helpers.models import flatten_choices
PAYMENT_PROVIDERS = []
@@ -178,10 +177,10 @@ class FilterForm(forms.Form):
elif isinstance(v, Model):
val = '"' + str(v) + '"'
elif isinstance(f, forms.MultipleChoiceField):
valdict = dict(flatten_choices(f.choices))
valdict = dict(f.choices)
val = ' or '.join([str(valdict.get(m)) for m in v])
elif isinstance(f, forms.ChoiceField):
val = str(dict(flatten_choices(f.choices)).get(v))
val = str(dict(f.choices).get(v))
elif isinstance(v, datetime):
val = date_format(v, 'SHORT_DATETIME_FORMAT')
elif isinstance(v, Decimal):
@@ -270,7 +269,6 @@ class OrderFilterForm(FilterForm):
matching_positions = OrderPosition.objects.filter(
Q(
Q(attendee_name_cached__icontains=u) | Q(attendee_email__icontains=u)
| Q(company__icontains=u)
| Q(secret__istartswith=u)
| Q(pseudonymization_id__istartswith=u)
)
@@ -850,18 +848,12 @@ class EventOrderExpertFilterForm(EventOrderFilterForm):
).distinct()
for q in self.event.questions.all():
if fdata.get(f'question_{q.pk}'):
if q.type in (Question.TYPE_BOOLEAN, Question.TYPE_NUMBER):
if q.type == Question.TYPE_BOOLEAN:
answers = QuestionAnswer.objects.filter(
question_id=q.pk,
orderposition__order_id=OuterRef('pk'),
answer__exact=fdata.get(f'question_{q.pk}')
)
elif q.type in (Question.TYPE_DATE, Question.TYPE_TIME, Question.TYPE_DATETIME):
answers = QuestionAnswer.objects.filter(
question_id=q.pk,
orderposition__order_id=OuterRef('pk'),
answer__exact=str(fdata.get(f'question_{q.pk}'))
)
elif q.type in (Question.TYPE_CHOICE, Question.TYPE_CHOICE_MULTIPLE):
answers = QuestionAnswer.objects.filter(
question_id=q.pk,

View File

@@ -25,8 +25,6 @@ import socket
from django import forms
from django.conf import settings
from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator
from django.utils.text import format_lazy
from django.utils.translation import gettext_lazy as _
from pretix.base.forms import SecretKeySettingsField, SettingsForm
@@ -56,15 +54,6 @@ class SMTPMailForm(SettingsForm):
smtp_password = SecretKeySettingsField(
label=_("Password"),
required=False,
validators=[RegexValidator(
r"^[A-Za-z0-9!\"#$%&'()*+,./:;<=>?@\^_`{}|~-]+$",
message=format_lazy(
_("The password contains characters not supported by our email system. Please only use characters "
"A-Z, a-z, 0-9, and common special characters ({characters})."),
characters=r'!"#$%%&\'()*+,-./:;<=>?@\^_`{}|~'
)
)]
)
smtp_use_tls = forms.BooleanField(
label=_("Use STARTTLS"),

View File

@@ -33,7 +33,6 @@
# 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 os.path
from datetime import date, datetime, time
from decimal import Decimal
@@ -69,7 +68,6 @@ from pretix.base.services.placeholders import FormPlaceholderMixin
from pretix.base.services.pricing import get_price
from pretix.control.forms import SplitDateTimeField
from pretix.control.forms.widgets import Select2
from pretix.helpers.hierarkey import clean_filename
from pretix.helpers.money import change_decimal_field
@@ -725,9 +723,6 @@ class OrderMailForm(forms.Form):
help_text=_("Will be ignored if tickets exceed a given size limit to ensure email deliverability."),
required=False
)
attach_new_order = forms.BooleanField(
required=False
)
attach_invoices = forms.ModelMultipleChoiceField(
label=_("Attach invoices"),
widget=forms.CheckboxSelectMultiple,
@@ -764,12 +759,6 @@ class OrderMailForm(forms.Form):
self.fields['attach_invoices'].queryset = order.invoices.all()
self._set_field_placeholders('message', ['event', 'order'])
self._set_field_placeholders('subject', ['event', 'order'])
if order.event.settings.mail_attachment_new_order:
self.fields['attach_new_order'].label = _('Attach {file}').format(
file=clean_filename(os.path.basename(order.event.settings.mail_attachment_new_order.name))
)
else:
del self.fields['attach_new_order']
class OrderPositionMailForm(OrderMailForm):

View File

@@ -148,7 +148,7 @@
<td>{{ e.item }}{% if e.variation %} {{ e.variation }}{% endif %}</td>
{% if request.event.has_subevents and not checkinlist.subevent %}
<td>
{{ e.subevent.name }} {{ e.subevent.get_date_range_display_with_times }}
{{ e.subevent.name }} {{ e.subevent.get_date_range_display }} {{ e.subevent.date_from|date:"TIME_FORMAT" }}
</td>
{% endif %}
{% if seats %}

View File

@@ -127,7 +127,8 @@
{% if request.event.has_subevents %}
{% if cl.subevent %}
<td>
{{ cl.subevent.name }} {{ cl.subevent.get_date_range_display_with_times }}
{{ cl.subevent.name }} {{ cl.subevent.get_date_range_display }}
{{ cl.subevent.date_from|date:"TIME_FORMAT" }}
</td>
{% else %}
<td>

View File

@@ -85,7 +85,7 @@
</td>
{% if request.event.has_subevents %}
<td>
{{ q.subevent.name }} {{ q.subevent.get_date_range_display_with_times }}
{{ q.subevent.name }} {{ q.subevent.get_date_range_display }} {{ q.subevent.date_from|date:"TIME_FORMAT" }}
</td>
{% endif %}
<td>{% if q.size == None %}Unlimited{% else %}{{ q.size }}{% endif %}</td>

View File

@@ -9,7 +9,6 @@
{% load eventsignal %}
{% load l10n %}
{% load phone_format %}
{% load getitem %}
{% block title %}
{% blocktrans trimmed with code=order.code %}
Order details: {{ code }}
@@ -398,7 +397,7 @@
{% elif c.auto_checked_in %}
<span class="fa fa-fw fa-magic text-success" data-toggle="tooltip_html" title="{{ c.list.name|force_escape|force_escape }}<br>{% blocktrans trimmed with date=c.datetime|date:'SHORT_DATETIME_FORMAT' %}Automatically checked in: {{ date }}{% endblocktrans %}{% if c.gate %}<br>{{ c.gate }}{% endif %}"></span>
{% else %}
<span class="fa fa-fw {% if c.list.consider_tickets_used %}text-success fa-check{% else %}text-muted fa-check-circle-o{% endif %}" data-toggle="tooltip_html" title="{{ c.list.name|force_escape|force_escape }}<br>{% blocktrans trimmed with date=c.datetime|date:'SHORT_DATETIME_FORMAT' %}Entry scan: {{ date }}{% endblocktrans %}{% if c.gate %}<br>{{ c.gate }}{% endif %}"></span>
<span class="fa fa-fw fa-check {% if c.list.consider_tickets_used %}text-success{% else %}text-muted{% endif %}" data-toggle="tooltip_html" title="{{ c.list.name|force_escape|force_escape }}<br>{% blocktrans trimmed with date=c.datetime|date:'SHORT_DATETIME_FORMAT' %}Entry scan: {{ date }}{% endblocktrans %}{% if c.gate %}<br>{{ c.gate }}{% endif %}"></span>
{% endif %}
{% endfor %}
{% endif %}
@@ -429,7 +428,11 @@
{% endif %}
{% if line.subevent %}
<br/>
<span class="fa fa-calendar fa-fw"></span> {{ line.subevent.name }} &middot; {{ line.subevent.get_date_range_display_with_times }}
<span class="fa fa-calendar fa-fw"></span> {{ line.subevent.name }} &middot; {{ line.subevent.get_date_range_display }}
{% if event.settings.show_times %}
<span class="fa fa-clock-o"></span>
{{ line.subevent.date_from|date:"TIME_FORMAT" }}
{% endif %}
{% endif %}
{% if line.used_membership %}
<br /><span class="fa fa-id-card fa-fw" aria-hidden="true"></span>
@@ -557,8 +560,8 @@
{% if line.street or line.zipcode or line.city or line.country %}
{{ line.street|default_if_none:""|linebreaksbr }}<br>
{{ line.zipcode|default_if_none:"" }} {{ line.city|default_if_none:"" }}<br>
{% if line.state %}{{ line.state_for_address }}<br>{% endif %}
{{ line.country.name|default_if_none:"" }}
{% if line.state %}<br>{{ line.state }}{% endif %}
{% else %}
<em>{% trans "not answered" %}</em>
{% endif %}
@@ -956,7 +959,7 @@
<dt>{% trans "Country" %}</dt>
<dd>{{ order.invoice_address.country.name|default:order.invoice_address.country_old }}</dd>
{% if order.invoice_address.state %}
<dt>{% trans "State" context "address" as state_label %}{{ COUNTRY_STATE_LABEL|getitem:order.invoice_address.country.code|default:state_label }}</dt>
<dt>{% trans "State" context "address" %}</dt>
<dd>{{ order.invoice_address.state_name }}</dd>
{% endif %}
{% if request.event.settings.invoice_address_vatid %}

View File

@@ -51,41 +51,6 @@
{{ log.parsed_data.subject }}</strong>
</p>
<pre>{{ log.parsed_data.message }}</pre>
<ul class="list-unstyled">
{% if log.parsed_data.attach_tickets %}
<li><span class="fa fa-files-o fa-fw"></span> {% trans "Tickets" %}</li>
{% endif %}
{% if log.parsed_data.attach_ical %}
<li><span class="fa fa-calendar-o fa-fw"></span> {% trans "Calendar invite" %}</li>
{% endif %}
{% if log.parsed_data.invoices %}
{% for i in log.parsed_invoices %}
<li>
<span class="fa fa-file-o fa-fw"></span>
<a href="{% url "control:event.invoice.download" invoice=i.pk event=request.event.slug organizer=request.event.organizer.slug %}" target="_blank">
{% if i.is_cancellation %}{% trans "Cancellation" context "invoice" %}{% else %}{% trans "Invoice" %}{% endif %}
{{ i.number }}
</a>
</li>
{% endfor %}
{% endif %}
{% if log.parsed_data.attach_other_files %}
{% for f in log.parsed_other_files %}
<li>
<span class="fa fa-file-o fa-fw"></span>
{{ f }}
</li>
{% endfor %}
{% endif %}
{% if log.parsed_data.attach_cached_files %}
{% for f in log.parsed_data.attach_cached_files %}
<li>
<span class="fa fa-file-o fa-fw"></span>
{{ f }}
</li>
{% endfor %}
{% endif %}
</ul>
{% endif %}
</li>
{% endfor %}

View File

@@ -19,9 +19,6 @@
{% bootstrap_field form.subject layout='horizontal' %}
{% bootstrap_field form.message layout='horizontal' %}
{% bootstrap_field form.attach_tickets layout='horizontal' %}
{% if form.attach_new_order %}
{% bootstrap_field form.attach_new_order layout='horizontal' %}
{% endif %}
{% if form.attach_invoices %}
{% bootstrap_field form.attach_invoices layout='horizontal' %}
{% endif %}

View File

@@ -7,8 +7,7 @@
{% block title %}{% trans "Order search" %}{% endblock %}
{% block content %}
<h1>{% trans "Order search" %}</h1>
<form class="form-horizontal" method="post">
{% csrf_token %}
<form class="form-horizontal" action="{% url "control:event.orders" event=request.event.slug organizer=request.event.organizer.slug %}" method="get">
{% for f in forms %}
{% bootstrap_form_errors f layout='control' %}
{% for field in f %}

View File

@@ -188,7 +188,10 @@
</td>
{% if request.event.has_subevents %}
<td>
{{ v.subevent.name }} {{ v.subevent.get_date_range_display_with_times }}
{{ v.subevent.name }} {{ v.subevent.get_date_range_display }}
{% if request.event.settings.show_times %}
{{ v.subevent.date_from|date:"TIME_FORMAT" }}
{% endif %}
</td>
{% endif %}
<td class="text-right flip">

View File

@@ -135,7 +135,6 @@ from pretix.control.views import PaginationMixin
from pretix.helpers import OF_SELF
from pretix.helpers.compat import CompatDeleteView
from pretix.helpers.format import SafeFormatter, format_map
from pretix.helpers.hierarkey import clean_filename
from pretix.helpers.safedownload import check_token
from pretix.presale.signals import question_form_fields
@@ -172,26 +171,6 @@ class OrderSearch(OrderSearchMixin, EventPermissionRequiredMixin, TemplateView):
ctx['forms'] = self.get_forms()
return ctx
def post(self, request, *args, **kwargs):
all_valid = True
for f in self.get_forms():
if not f.is_valid():
all_valid = False
if all_valid:
data = request.POST.copy()
data.pop('csrfmiddlewaretoken', None)
return redirect(reverse(
"control:event.orders",
kwargs={
"event": request.event.slug,
"organizer": request.event.organizer.slug,
}
) + '?' + data.urlencode())
else:
messages.error(request, _("We could not process your input. See below for details."))
return self.get(request, *args, **kwargs)
class BaseOrderBulkActionView(OrderSearchMixin, EventPermissionRequiredMixin, AsyncFormView):
template_name = 'pretixcontrol/orders/bulk_action.html'
@@ -2385,9 +2364,6 @@ class OrderSendMail(EventPermissionRequiredMixin, OrderViewMixin, FormView):
self.request.user, auto_email=False,
attach_tickets=form.cleaned_data.get('attach_tickets', False),
invoices=form.cleaned_data.get('attach_invoices', []),
attach_other_files=[a for a in [
self.request.event.settings.get('mail_attachment_new_order', as_type=str, default='')[len('file://'):]
] if a] if form.cleaned_data.get('attach_new_order', False) else [],
)
messages.success(self.request,
_('Your message has been queued and will be sent to {}.'.format(order.email)))
@@ -2456,9 +2432,6 @@ class OrderPositionSendMail(OrderSendMail):
'pretix.event.order.position.email.custom_sent',
self.request.user,
attach_tickets=form.cleaned_data.get('attach_tickets', False),
attach_other_files=[a for a in [
self.request.event.settings.get('mail_attachment_new_order', as_type=str, default='')[len('file://'):]
] if a] if form.cleaned_data.get('attach_new_order', False) else [],
)
messages.success(self.request,
_('Your message has been queued and will be sent to {}.'.format(position.attendee_email)))
@@ -2488,23 +2461,6 @@ class OrderEmailHistory(EventPermissionRequiredMixin, OrderViewMixin, ListView):
)
return qs
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
for l in ctx["logs"]:
invoice_ids = l.parsed_data.get("invoices")
if invoice_ids:
if type(invoice_ids) is int:
invoice_ids = [invoice_ids]
l.parsed_invoices = Invoice.objects.filter(
event=self.request.event,
pk__in=invoice_ids,
)
if l.parsed_data.get("attach_other_files"):
l.parsed_other_files = [
clean_filename(os.path.basename(f)) for f in l.parsed_data["attach_other_files"]
]
return ctx
class AnswerDownload(EventPermissionRequiredMixin, OrderViewMixin, ListView):
permission = 'can_view_orders'

View File

@@ -44,13 +44,3 @@ def modelcopy(obj: models.Model, **kwargs):
else:
setattr(n, f.name, copy.deepcopy(val))
return n
# django 5 contains this in django.utils.choices.flatten_choices
def flatten_choices(choices):
"""Flatten choices by removing nested values."""
for value_or_group, label_or_nested in choices or ():
if isinstance(label_or_nested, (list, tuple)):
yield from label_or_nested
else:
yield value_or_group, label_or_nested

View File

@@ -4,8 +4,8 @@ msgstr ""
"Project-Id-Version: 1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-02-25 10:10+0000\n"
"PO-Revision-Date: 2025-03-11 07:00+0000\n"
"Last-Translator: Mikkel Ricky <rimi@aarhus.dk>\n"
"PO-Revision-Date: 2025-01-14 09:56+0000\n"
"Last-Translator: Nikolai <nikolai@lengefeldt.de>\n"
"Language-Team: Danish <https://translate.pretix.eu/projects/pretix/pretix/da/"
">\n"
"Language: da\n"
@@ -13,7 +13,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.10.2\n"
"X-Generator: Weblate 5.9.2\n"
#: pretix/_base_settings.py:87
msgid "English"
@@ -33,7 +33,7 @@ msgstr "Arabisk"
#: pretix/_base_settings.py:91
msgid "Basque"
msgstr "Basque"
msgstr ""
#: pretix/_base_settings.py:92
msgid "Catalan"
@@ -53,7 +53,7 @@ msgstr "Tjekkisk"
#: pretix/_base_settings.py:96
msgid "Croatian"
msgstr "Kroatisk"
msgstr ""
#: pretix/_base_settings.py:97
msgid "Danish"
@@ -93,7 +93,7 @@ msgstr "Italiensk"
#: pretix/_base_settings.py:106
msgid "Japanese"
msgstr "Japansk"
msgstr ""
#: pretix/_base_settings.py:107
msgid "Latvian"
@@ -101,7 +101,7 @@ msgstr "Lettisk"
#: pretix/_base_settings.py:108
msgid "Norwegian Bokmål"
msgstr "Norsk"
msgstr "Norsk (Bokmål)"
#: pretix/_base_settings.py:109
msgid "Polish"
@@ -109,7 +109,7 @@ msgstr "Polsk"
#: pretix/_base_settings.py:110
msgid "Portuguese (Portugal)"
msgstr "Portugisisk"
msgstr "Portugisisk (Portugal)"
#: pretix/_base_settings.py:111
msgid "Portuguese (Brazil)"
@@ -148,7 +148,7 @@ msgid ""
"Full device access (reading and changing orders and gift cards, reading of "
"products and settings)"
msgstr ""
"Fuld adgang til enhed (se og ændre bestillinger, gavekort, produkter og "
"Fuld adgang til enhed (se og ændre bestillinger og gavekort, se produkter og "
"indstillinger)"
#: pretix/api/auth/devicesecurity.py:80
@@ -157,7 +157,8 @@ msgstr "pretixSCAN"
#: pretix/api/auth/devicesecurity.py:118
msgid "pretixSCAN (kiosk mode, no order sync, no search)"
msgstr "pretixSCAN (kiosk, ingen synkronisering af bestillinger, ingen søgning)"
msgstr ""
"pretixSCAN (kiosk-modus, ingen synkronisering af bestillinger, ingen søgning)"
#: pretix/api/auth/devicesecurity.py:153
msgid "pretixSCAN (online only, no order sync)"
@@ -165,15 +166,15 @@ msgstr "pretixSCAN (kun online, ingen synkronisering af bestillinger)"
#: pretix/api/models.py:39 pretix/base/models/customers.py:402
msgid "Application name"
msgstr "Ansøger navn"
msgstr "Applikationsnavn"
#: pretix/api/models.py:42 pretix/base/models/customers.py:425
msgid "Redirection URIs"
msgstr "Viderestillings URL's"
msgstr "Viderestillingsurler"
#: pretix/api/models.py:43 pretix/base/models/customers.py:426
msgid "Allowed URIs list, space separated"
msgstr "Liste af tilladte URL adskilt af mellemrum"
msgstr "Liste af tilladte urler adskilt af mellemrum"
#: pretix/api/models.py:47
msgid "Allowed Post Logout URIs list, space separated"
@@ -200,12 +201,12 @@ msgstr "Target URL"
#: pretix/api/models.py:118 pretix/base/models/devices.py:122
#: pretix/base/models/organizer.py:286
msgid "All events (including newly created ones)"
msgstr "Alle arrangementer (inkl. ny oprettet)"
msgstr "Alle arrangementer (inkl. nyoprettede begivenheder)"
#: pretix/api/models.py:119 pretix/base/models/devices.py:123
#: pretix/base/models/organizer.py:287
msgid "Limit to events"
msgstr "Vis kun events"
msgstr "Vis kun arrangementer"
#: pretix/api/models.py:120 pretix/base/exporters/orderlist.py:284
#: pretix/base/exporters/orderlist.py:1077
@@ -260,9 +261,10 @@ msgid "Unknown plugin: '{name}'."
msgstr "Ukendt plugin: '{name}'."
#: pretix/api/serializers/event.py:296
#, python-brace-format
#, fuzzy, python-brace-format
#| msgid "Unknown plugin: '{name}'."
msgid "Restricted plugin: '{name}'."
msgstr "Begrænset plugin: '{name}'."
msgstr "Ukendt plugin: '{name}'."
#: pretix/api/serializers/item.py:86 pretix/api/serializers/item.py:148
#: pretix/api/serializers/item.py:359
@@ -508,8 +510,10 @@ msgid "Order denied"
msgstr "Bestilling afvist"
#: pretix/api/webhooks.py:313
#, fuzzy
#| msgid "Order denied"
msgid "Order deleted"
msgstr "Bestilling slettet"
msgstr "Bestilling afvist"
#: pretix/api/webhooks.py:317
msgid "Ticket checked in"
@@ -2601,7 +2605,7 @@ msgstr "Gavekortoverførsler"
#: pretix/base/exporters/orderlist.py:1288
msgctxt "export_category"
msgid "Gift cards"
msgstr "Voucher"
msgstr "Gavekort"
#: pretix/base/exporters/orderlist.py:1184
msgid "Download a spreadsheet of all gift card transactions."
@@ -2681,7 +2685,7 @@ msgid ""
"Download a spreadsheet of all payments or refunds that involve gift cards."
msgstr ""
"Download et regneark med alle betalinger og tilbagebetalinger, som "
"indeholder voucher"
"indeholder gavekort."
#: pretix/base/exporters/orderlist.py:1259
#: pretix/control/templates/pretixcontrol/giftcards/payment.html:16
@@ -2693,11 +2697,11 @@ msgstr "Udsteder"
#: pretix/control/templates/pretixcontrol/organizers/edit.html:156
#: pretix/plugins/reports/accountingreport.py:898
msgid "Gift cards"
msgstr "Voucher"
msgstr "Gavekort"
#: pretix/base/exporters/orderlist.py:1289
msgid "Download a spreadsheet of all gift cards including their current value."
msgstr "Download et regneark af alle voucher's inkl. deres aktuelle værdi."
msgstr "Download et regneark af alle gavekort inkl. deres aktuelle værdi."
#: pretix/base/exporters/orderlist.py:1296
msgid "Show value at"
@@ -5186,7 +5190,7 @@ msgstr "Den valgte medietype kan på dette tidspunkt ikke bruges til billetter."
#: pretix/base/models/items.py:996
msgid ""
"The selected media type does not support usage for gift cards currently."
msgstr "Den valgte medietype kan lige nu ikke anvendes som voucher."
msgstr "Den valgte medietype kan for tiden ikke bruges til gavekort."
#: pretix/base/models/items.py:998
msgid ""
@@ -5194,8 +5198,8 @@ msgid ""
"Instead, gift cards for some reusable media types can be created or re-"
"charged directly at the POS."
msgstr ""
"Du kan på dette tidspunkt ikke oprette voucher med en politik for "
"genanvendelige medier. Voucher for nogle genanvendelige medier kan i stedet "
"Du kan på dette tidspunkt ikke oprette gavekort med en politik for "
"genanvendelige medier. Gavekort for nogle genanvendelige medier kan i stedet "
"for oprettes eller oplades direkte ved POS'en."
#: pretix/base/models/items.py:1006
@@ -6122,7 +6126,7 @@ msgstr "Kan administrere genanvendelige medier"
#: pretix/base/models/organizer.py:319
msgid "Can manage gift cards"
msgstr "Kan administrere voucher"
msgstr "Kan administrere gavekort"
#: pretix/base/models/organizer.py:323
msgid "Can change event settings"
@@ -7158,7 +7162,7 @@ msgstr "Dette gavekort kan kun blive brugt i testmodus."
#: pretix/base/payment.py:1437 pretix/base/payment.py:1500
#: pretix/base/payment.py:1549
msgid "Only test gift cards can be used in test mode."
msgstr "Kun testvouchers kan bruges under testmodus."
msgstr "Kun testgavekort kan bruges under testmodus."
#: pretix/base/payment.py:1439 pretix/base/payment.py:1503
#: pretix/base/payment.py:1551
@@ -7176,7 +7180,7 @@ msgstr "Dette gavekort bliver allerede brugt til din betaling."
#: pretix/base/payment.py:1460 pretix/base/payment.py:1486
#: pretix/base/payment.py:1529
msgid "You cannot pay with gift cards when buying a gift card."
msgstr "Du kan ikke betale med en voucher, når du køber en voucher"
msgstr "Du kan ikke betale med et gavekort, når du køber et gavekort."
#: pretix/base/payment.py:1476 pretix/base/payment.py:1519
msgid ""
@@ -8026,7 +8030,7 @@ msgid ""
"You entered a gift card instead of a voucher. Gift cards can be entered "
"later on when you're asked for your payment details."
msgstr ""
"Du har indtastet et voucher i stedet for en voucher. Voucher kan indtastes "
"Du har indtastet et gavekort i stedet for en voucher. Gavekort kan indtastes "
"senere, når du bliver bedt om dine betalingsoplysninger."
#: pretix/base/services/cart.py:216
@@ -8998,8 +9002,8 @@ msgid ""
"different tickets or gift cards later."
msgstr ""
"Funktionen \"Genanvendelige medier\" gør det muligt at forbinde billetter og "
"voucher med fysiske medier som armbånd eller chipkort, der kan genbruges til "
"andre billetter eller voucher senere."
"gavekort med fysiske medier som armbånd eller chipkort, der kan genbruges "
"til andre billetter eller gavekort senere."
#: pretix/base/settings.py:218
msgid "Length of barcodes"
@@ -9825,11 +9829,6 @@ msgid ""
"page. Note that pretix still is a system built around events and the date "
"may still show up in other places."
msgstr ""
"Fjern markeringen i denne boks, hvis du kun sælger noget uden en specifik "
"dato, såsom en voucher eller en billet, der kan bruges når som helst. "
"Systemet vil derefter stoppe med at vise eventdatoen nogle steder, såsom "
"eventets startside. Bemærk, at pretix stadig er et system bygget omkring "
"events, og datoen kan stadig vises andre steder."
#: pretix/base/settings.py:1326
msgid "Show event end date"
@@ -10408,8 +10407,9 @@ msgid ""
msgstr ""
#: pretix/base/settings.py:1976 pretix/base/settings.py:1986
#, fuzzy
msgid "All refunds are issued as gift cards"
msgstr "Alle refunderinger udstedes som vouchers."
msgstr "Kreditkort"
#: pretix/base/settings.py:1977 pretix/base/settings.py:1987
msgid "Do not handle refunds automatically at all"
@@ -11599,9 +11599,6 @@ msgid ""
"the year after this many years. If you keep it empty, gift cards do not have "
"an explicit expiry date."
msgstr ""
"Hvis du angiver et tal her, udløber vouchers som standard ved udgangen af "
"året efter det angivne antal år. Hvis du lader feltet være tomt, vil "
"vouchers ikke have en specifik udløbsdato."
#: pretix/base/settings.py:3301
msgid "Enable cookie consent management features"
@@ -12843,8 +12840,6 @@ msgid ""
"You have configured gift cards to be valid {} years plus the year the gift "
"card is issued in."
msgstr ""
"Du har konfigureret vouchers til at være gyldige i {} år plus det år, hvor "
"voucheren udstedes."
#: pretix/control/forms/event.py:787
msgid "Tax rule for payment fees"
@@ -14209,9 +14204,6 @@ msgid ""
"restrict the validity of the gift card. A validity of gift cards can be set "
"in your organizer settings."
msgstr ""
"Angiv ikke en specifik gyldighed for voucher-produkter, da det ikke vil "
"begrænse vouchernes gyldighed. Gyldigheden af vouchers kan indstilles i dine "
"arrangørindstillinger."
#: pretix/control/forms/item.py:785 pretix/control/forms/item.py:1052
msgid ""
@@ -14689,12 +14681,6 @@ msgid ""
"manual refund to-do list. Do not check if you want to refund some of the "
"orders by offsetting with different orders or issuing gift cards."
msgstr ""
"Manuelle refunderinger oprettes og vises på listen over manuelle "
"refunderinger. Når dette kombineres med den automatiske "
"refunderingsfunktion, vil kun betalinger med en betalingsmetode, der ikke "
"understøtter automatiske refunderinger, være på din liste over manuelle "
"refunderinger. Fjern markeringen, hvis du vil refundere nogle ordrer ved at "
"udligne med andre ordrer eller udstede vouchers."
#: pretix/control/forms/orders.py:868
msgid ""
@@ -19971,7 +19957,6 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/item/index.html:66
msgid "Examples: Merchandise, donations, gift cards, add-ons to a main ticket."
msgstr ""
"Eksempler: Merchandise, donationer, vouchers, tilføjelser til en billet."
#: pretix/control/templates/pretixcontrol/item/create.html:68
#: pretix/control/templates/pretixcontrol/item/index.html:76
@@ -21958,10 +21943,6 @@ msgid ""
"is to include an explanation and a link to their order using the here "
"provided email functionality."
msgstr ""
"Da du refunderer dine kunders ordrer til vouchers, bør du forklare dem, "
"hvordan de får adgang til deres vouchers. Den nemmeste måde at gøre dette på "
"er at inkludere en forklaring og et link til deres ordre ved hjælp af den "
"her tilgængelige e-mailfunktion."
#: pretix/control/templates/pretixcontrol/orders/cancel.html:64
msgid ""
@@ -22938,7 +22919,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/organizers/edit.html:245
#: pretix/control/templates/pretixcontrol/organizers/edit.html:277
msgid "NFC media can currently only be connected to gift cards."
msgstr "NFC-medier kan i øjeblikket kun tilknyttes vouchers."
msgstr ""
#: pretix/control/templates/pretixcontrol/organizers/edit.html:251
msgid ""
@@ -23049,20 +23030,19 @@ msgid "Invite organizer"
msgstr "Alle arrangører"
#: pretix/control/templates/pretixcontrol/organizers/giftcard_acceptance_list.html:8
#, fuzzy
msgid "Gift cards acceptance"
msgstr "Accept af vouchers."
msgstr "Gavekort"
#: pretix/control/templates/pretixcontrol/organizers/giftcard_acceptance_list.html:11
msgid ""
"This feature allows you to configure acceptance of gift cards across "
"multiple organizer accounts."
msgstr ""
"Denne funktion giver dig mulighed for at konfigurere accept af vouchers på "
"tværs af flere arrangørkonti."
#: pretix/control/templates/pretixcontrol/organizers/giftcard_acceptance_list.html:18
msgid "Other organizers you accept gift cards from"
msgstr "Andre arrangører, du accepterer vouchers fra."
msgstr ""
#: pretix/control/templates/pretixcontrol/organizers/giftcard_acceptance_list.html:23
msgid ""
@@ -23070,9 +23050,6 @@ msgid ""
"do so, the other organizer can add you to their list and afterwards, you can "
"confirm this here."
msgstr ""
"Du accepterer endnu ikke vouchers fra andre arrangører. Hvis du ønsker at "
"gøre det, kan den anden arrangør tilføje dig til deres liste, og derefter "
"kan du bekræfte dette her."
#: pretix/control/templates/pretixcontrol/organizers/giftcard_acceptance_list.html:49
#: pretix/control/templates/pretixcontrol/organizers/giftcard_acceptance_list.html:128
@@ -23099,7 +23076,7 @@ msgstr "Tidslinje"
#: pretix/control/templates/pretixcontrol/organizers/giftcard_acceptance_list.html:84
msgid "Other organizers accepting gift cards from you"
msgstr "Andre arrangører, der accepterer vouchers fra dig"
msgstr ""
#: pretix/control/templates/pretixcontrol/organizers/giftcard_acceptance_list.html:87
msgid ""
@@ -23110,11 +23087,6 @@ msgid ""
"responsibility to handle the exchange of money to offset the transactions "
"between the two organizers."
msgstr ""
"Du kan invitere andre arrangører til at acceptere dine vouchers. Efter du "
"har gjort dette, skal de gå til den samme side i deres konto og acceptere "
"din invitation. Bemærk, at andre arrangører også vil kunne tilføje penge til "
"vouchers, som du skal indsamle fra dem. Det er dit ansvar at håndtere "
"pengeudvekslingen for at udligne transaktionerne mellem de to arrangører."
#: pretix/control/templates/pretixcontrol/organizers/giftcard_acceptance_list.html:95
msgid ""
@@ -23136,16 +23108,15 @@ msgid "Invite new organizer"
msgstr "Opret arrangør"
#: pretix/control/templates/pretixcontrol/organizers/giftcards.html:8
#, fuzzy
msgid "Issued gift cards"
msgstr "Udstedte vouchers"
msgstr "Kreditkort"
#: pretix/control/templates/pretixcontrol/organizers/giftcards.html:13
msgid ""
"You haven't issued any gift cards yet. You can either set up a product in an "
"event shop to sell gift cards, or you can manually issue gift cards."
msgstr ""
"Du har endnu ikke udstedt nogen vouchers. Du kan enten oprette et produkt i "
"en eventbutik for at sælge vouchers, eller du kan manuelt udstede vouchers."
#: pretix/control/templates/pretixcontrol/organizers/giftcards.html:20
#: pretix/control/templates/pretixcontrol/organizers/giftcards.html:50
@@ -26537,7 +26508,7 @@ msgstr "Det valgte spørgsmål er blevet slettet."
#: pretix/control/views/organizer.py:1520
#: pretix/control/views/organizer.py:1557
msgid "Gift cards are not allowed to have negative values."
msgstr "Vouchers må ikke have negative værdier."
msgstr ""
#: pretix/control/views/organizer.py:1547
#, fuzzy
@@ -33994,7 +33965,7 @@ msgstr ""
#: pretix/settings.py:802
msgid "Kosovo"
msgstr "Kosovo"
msgstr ""
#~ msgid "Show event times and dates on the ticket shop"
#~ msgstr "Vis arrangementers tidspunkter og datoer i billet-shoppen"

View File

@@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-02-25 10:10+0000\n"
"PO-Revision-Date: 2025-03-19 01:00+0000\n"
"Last-Translator: Hector <hector@alpakafest.com>\n"
"PO-Revision-Date: 2025-03-01 15:14+0000\n"
"Last-Translator: CVZ-es <damien.bremont@casadevelazquez.org>\n"
"Language-Team: Spanish <https://translate.pretix.eu/projects/pretix/pretix/"
"es/>\n"
"Language: es\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.10.3\n"
"X-Generator: Weblate 5.10.1\n"
#: pretix/_base_settings.py:87
msgid "English"
@@ -1276,7 +1276,7 @@ msgstr ""
#: pretix/base/exporters/invoices.py:178
msgid "Invoice data"
msgstr "Datos de facturación"
msgstr "Datos de la factura"
#: pretix/base/exporters/invoices.py:179
msgid ""
@@ -1444,7 +1444,7 @@ msgstr "País"
#: pretix/base/exporters/invoices.py:211 pretix/base/exporters/invoices.py:337
msgid "Tax ID"
msgstr "NIF"
msgstr "CIF"
#: pretix/base/exporters/invoices.py:212 pretix/base/exporters/invoices.py:220
#: pretix/base/exporters/invoices.py:338 pretix/base/exporters/invoices.py:346
@@ -3337,7 +3337,7 @@ msgstr "Importe"
#, python-brace-format
msgctxt "invoice"
msgid "Single price: {net_price} net / {gross_price} gross"
msgstr "Precio unitario: {net_price} neto / {gross_price} bruto"
msgstr "Precio único: {net_price} neto / {gross_price} bruto"
#: pretix/base/invoice.py:724
#, python-brace-format
@@ -11741,12 +11741,12 @@ msgid ""
"preview, so we recommend to make sure it still looks good if only the center "
"square is shown. If you do not fill this, we will use the logo given above."
msgstr ""
"Esta imagen se utilizará como vista previa si publica enlaces de su taquilla "
"Esta imagen se utilizará como vista previa si publica enlaces a su taquilla "
"virtual en las redes sociales. Facebook recomienda utilizar un tamaño de "
"imagen de 1200 x 630 píxeles; sin embargo, algunas plataformas como WhatsApp "
"y Reddit solo muestran una vista previa del cuadrado, por lo que "
"recomendamos asegurarse de que aún se vea bien, solo se muestra el cuadrado "
"central. Si no completa esto, usaremos el logotipo de la parte superior."
"central. Si no completa esto, usaremos el logotipo que figura arriba."
#: pretix/base/settings.py:3005
msgid "Logo image"

View File

@@ -4,7 +4,7 @@ msgstr ""
"Project-Id-Version: 1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-02-25 10:10+0000\n"
"PO-Revision-Date: 2025-03-17 17:00+0000\n"
"PO-Revision-Date: 2025-03-01 15:14+0000\n"
"Last-Translator: CVZ-es <damien.bremont@casadevelazquez.org>\n"
"Language-Team: French <https://translate.pretix.eu/projects/pretix/pretix/fr/"
">\n"
@@ -13,7 +13,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.10.3\n"
"X-Generator: Weblate 5.10.1\n"
#: pretix/_base_settings.py:87
msgid "English"
@@ -11868,9 +11868,9 @@ msgstr ""
"billetterie sur les réseaux sociaux. Facebook conseille dutiliser une "
"taille dimage de 1200 x 630 pixels, mais certaines plates-formes comme "
"WhatsApp et Reddit naffichent quun aperçu carré, nous vous recommandons "
"donc de vous assurer quil a toujours de l'espace bien que seul le carré "
"central soit affiché. Si vous ne le remplissez pas, nous utiliserons le logo "
"de la partie supérieure."
"donc de vous assurer quil a toujours lair bien que seul le carré central "
"est affiché. Si vous ne le remplissez pas, nous utiliserons le logo donné ci-"
"dessus."
#: pretix/base/settings.py:3005
msgid "Logo image"

View File

@@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-02-25 10:10+0000\n"
"PO-Revision-Date: 2025-03-16 10:17+0000\n"
"Last-Translator: Robert Rigo <kontakt@bicikli.hr>\n"
"PO-Revision-Date: 2025-03-04 16:16+0000\n"
"Last-Translator: Martin Gross <gross@rami.io>\n"
"Language-Team: Croatian <https://translate.pretix.eu/projects/pretix/"
"pretix-js/hr/>\n"
"Language: hr\n"
@@ -18,7 +18,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
"X-Generator: Weblate 5.10.3\n"
"X-Generator: Weblate 5.10.2\n"
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
@@ -692,9 +692,8 @@ msgstr ""
#: pretix/static/pretixpresale/js/ui/cart.js:50
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] "Stavke u vašoj košarici rezervirane su još jednu  minutu."
msgstr[1] "Stavke u vašoj košarici rezervirane su još {num} minute."
msgstr[2] "Stavke u vašoj košarici rezervirane su još {num} minuta."
msgstr[0] ""
msgstr[1] ""
#: pretix/static/pretixpresale/js/ui/main.js:203
msgid "The organizer keeps %(currency)s %(amount)s"

File diff suppressed because it is too large Load Diff

View File

@@ -8,16 +8,16 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-02-25 10:10+0000\n"
"PO-Revision-Date: 2025-03-16 19:00+0000\n"
"Last-Translator: \"Luca Martinelli [Sannita]\" <sannita@gmail.com>\n"
"Language-Team: Italian <https://translate.pretix.eu/projects/pretix/"
"pretix-js/it/>\n"
"PO-Revision-Date: 2023-05-18 01:00+0000\n"
"Last-Translator: M C <micasadmail@gmail.com>\n"
"Language-Team: Italian <https://translate.pretix.eu/projects/pretix/pretix-"
"js/it/>\n"
"Language: it\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.10.3\n"
"X-Generator: Weblate 4.17\n"
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
@@ -210,7 +210,7 @@ msgstr "Cambia direzione"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:38
msgid "Entry"
msgstr "Ingresso"
msgstr "Inserimento"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:39
msgid "Exit"
@@ -455,7 +455,7 @@ msgstr "Varianti prodotto"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:107
msgid "Gate"
msgstr "Cancello"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:111
msgid "Current date and time"
@@ -523,11 +523,11 @@ msgstr "Almeno una delle condizioni sottostanti (oppure)"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:184
msgid "Event start"
msgstr "Inizio evento"
msgstr "Evento inizia"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:185
msgid "Event end"
msgstr "Fine evento"
msgstr "Evento termina"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:186
msgid "Event admission"

View File

@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-02-25 10:10+0000\n"
"PO-Revision-Date: 2025-03-17 17:00+0000\n"
"PO-Revision-Date: 2025-02-04 20:00+0000\n"
"Last-Translator: Hijiri Umemoto <hijiri@umemoto.org>\n"
"Language-Team: Japanese <https://translate.pretix.eu/projects/pretix/pretix/"
"ja/>\n"
@@ -17,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Weblate 5.10.3\n"
"X-Generator: Weblate 5.9.2\n"
#: pretix/_base_settings.py:87
msgid "English"
@@ -57,7 +57,7 @@ msgstr "チェコ語"
#: pretix/_base_settings.py:96
msgid "Croatian"
msgstr "クロアチア語"
msgstr ""
#: pretix/_base_settings.py:97
msgid "Danish"
@@ -4065,8 +4065,10 @@ msgid "Grant type"
msgstr "グラントタイプ"
#: pretix/base/models/customers.py:420
#, fuzzy
#| msgid "Required question"
msgid "Require PKCE extension"
msgstr "PKCEエクステンションを要求"
msgstr "質問を要求"
#: pretix/base/models/customers.py:432
msgid "Allowed access scopes"
@@ -6949,9 +6951,11 @@ msgid "The payment for this invoice has already been received."
msgstr "この請求書の支払いはすでに受領済みです。"
#: pretix/base/payment.py:970
#, fuzzy
#| msgid "This payment can not be canceled at the moment."
msgid ""
"This payment is already being processed and can not be canceled any more."
msgstr "この支払いは処理中のため、キャンセルできません。"
msgstr "現時点ではこの支払いはキャンセルできません。"
#: pretix/base/payment.py:984
msgid "Automatic refunds are not supported by this payment provider."
@@ -9649,8 +9653,10 @@ msgstr ""
"される言語に関連しています(例:英語)。"
#: pretix/base/settings.py:1311
#, fuzzy
#| msgid "This is not an event series."
msgid "This shop represents an event"
msgstr "このショップは、イベントを代理しています"
msgstr "これはイベントシリーズではありません。"
#: pretix/base/settings.py:1313
msgid ""
@@ -9660,11 +9666,6 @@ msgid ""
"page. Note that pretix still is a system built around events and the date "
"may still show up in other places."
msgstr ""
"ギフトカードやいつでも使用できるチケットなど、特定の日付のないもののみを販売"
"している場合は、このボックスのチェックを外します。その後、イベント開始ページ"
"などの一部の場所で、システムはイベント日付の表示を停止します。Pretixはまだイ"
"ベントを中心に構築されたシステムであり、日付は他の場所でも表示される可能性が"
"あることに注意してください。"
#: pretix/base/settings.py:1326
msgid "Show event end date"
@@ -14979,7 +14980,7 @@ msgstr "電話番号の入力欄"
#: pretix/control/forms/organizer.py:1047
msgctxt "sso_oidc"
msgid "Query parameters"
msgstr "クエリのパラメータ"
msgstr ""
#: pretix/control/forms/organizer.py:1048
#, python-brace-format
@@ -14987,8 +14988,7 @@ msgctxt "sso_oidc"
msgid ""
"Optional query parameters, that will be added to calls to the authorization "
"endpoint. Enter as: {example}"
msgstr "認証エンドポイントへの呼び出しに追加されるオプションのクエリパラメータ。この"
"ように入力: {example}"
msgstr ""
#: pretix/control/forms/organizer.py:1109
msgid "Invalidate old client secret and generate a new one"
@@ -23978,8 +23978,10 @@ msgid "Size (mm)"
msgstr "サイズmm"
#: pretix/control/templates/pretixcontrol/pdf/index.html:327
#, fuzzy
#| msgid "Text color"
msgid "QR color"
msgstr "QRコードの色"
msgstr "テキストの色"
#: pretix/control/templates/pretixcontrol/pdf/index.html:342
msgid "Render without whitespace"
@@ -34088,12 +34090,17 @@ msgstr ""
"更はできません。"
#: pretix/presale/views/order.py:1646
#, fuzzy
#| msgid ""
#| "You may not change your order in a way that increases the total price "
#| "since payments are no longer being accepted for this event."
msgid ""
"You may not change your order in a way that requires additional payment "
"while we are processing your current payment. Please check back after your "
"current payment has been accepted."
msgstr "現在の支払いを処理する間、追加の支払いが必要な方法で注文を変更することはでき"
"ません。現在の支払いが承認されたら、また確認してください。"
msgstr ""
"支払いはこのイベントでは受け付けていないため、合計金額を増やすような注文の変"
"更はできません。"
#: pretix/presale/views/order.py:1662 pretix/presale/views/order.py:1693
msgid "You cannot change this order."

File diff suppressed because it is too large Load Diff

View File

@@ -7,8 +7,8 @@ msgstr ""
"Project-Id-Version: 1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-02-25 10:10+0000\n"
"PO-Revision-Date: 2025-03-11 15:09+0000\n"
"Last-Translator: MaartenUreel <maarten@ureel.be>\n"
"PO-Revision-Date: 2025-03-02 12:55+0000\n"
"Last-Translator: Tim Maurizio Dullaart <Tim.maurizio@gmail.com>\n"
"Language-Team: Dutch <https://translate.pretix.eu/projects/pretix/pretix/nl/>"
"\n"
"Language: nl\n"
@@ -16,7 +16,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.10.2\n"
"X-Generator: Weblate 5.10.1\n"
#: pretix/_base_settings.py:87
msgid "English"
@@ -3761,7 +3761,7 @@ msgstr ""
#: pretix/base/modelimport_vouchers.py:306 pretix/base/models/vouchers.py:519
#, python-brace-format
msgid "You need to choose the product \"{prod}\" for this seat."
msgstr "U dient het product \"{prod}\" te selecteren voor deze zitplaats."
msgstr "U moet het product \"{prod}\" kiezen voor deze stoel."
#: pretix/base/modelimport_vouchers.py:318 pretix/base/models/vouchers.py:285
#: pretix/control/templates/pretixcontrol/vouchers/index.html:129
@@ -4361,7 +4361,7 @@ msgstr "Evenementenreeks"
#: pretix/base/models/event.py:635 pretix/base/models/event.py:1513
msgid "Seating plan"
msgstr "Zitplaatsplattegrond"
msgstr "Stoelplattegrond"
#: pretix/base/models/event.py:642 pretix/base/models/items.py:675
msgid "Sell on all sales channels"
@@ -6285,29 +6285,27 @@ msgstr "Btw-tarief"
#: pretix/base/models/tax.py:171
msgctxt "tax_code"
msgid "Services outside of scope of tax"
msgstr "Niet belastbaar"
msgstr ""
#: pretix/base/models/tax.py:174
msgctxt "tax_code"
msgid "Exempt from tax (no reason given)"
msgstr "Belastingvrij (geen reden opgegeven)"
msgstr ""
#: pretix/base/models/tax.py:177
msgctxt "tax_code"
msgid "Zero-rated goods"
msgstr "Vrijgestelde producten"
msgstr ""
#: pretix/base/models/tax.py:180
msgctxt "tax_code"
msgid "Free export item, VAT not charged"
msgstr "Vrije uitvoer, geen BTW"
msgstr ""
#: pretix/base/models/tax.py:183
msgctxt "tax_code"
msgid "VAT exempt for EEA intra-community supply of goods and services"
msgstr ""
"BTW vrijgesteld voor EEA intracommunautaire leveringen van goederen en "
"diensten"
#: pretix/base/models/tax.py:187
#, fuzzy
@@ -6319,7 +6317,7 @@ msgstr "Sociale functies"
#: pretix/base/models/tax.py:189
msgctxt "tax_code"
msgid "Canary Islands general indirect tax"
msgstr "Canarische Eilanden algemeen belastingtarief"
msgstr ""
#: pretix/base/models/tax.py:190
msgctxt "tax_code"
@@ -6329,18 +6327,16 @@ msgstr ""
#: pretix/base/models/tax.py:191
msgctxt "tax_code"
msgid "Transferred (VAT), only in Italy"
msgstr "Overgedragen (BTW), enkel in Italië"
msgstr ""
#: pretix/base/models/tax.py:195
msgid "Exempt with specific reason"
msgstr "Uitgesloten met specifieke reden"
msgstr ""
#: pretix/base/models/tax.py:198
msgctxt "tax_code"
msgid "Exempt based on article 79, point c of Council Directive 2006/112/EC"
msgstr ""
"Uitgesloten onder artikel 79, punt c van de richtlijn 2006/112/EG van de "
"Raad van de EU"
#: pretix/base/models/tax.py:205 pretix/base/models/tax.py:218
#: pretix/base/models/tax.py:244
@@ -6350,8 +6346,6 @@ msgid ""
"Exempt based on article {article}, section {section} ({letter}) of Council "
"Directive 2006/112/EC"
msgstr ""
"Uitgesloten op basis van artikel {article}, paragraaf {section} ({letter}) "
"van de richtlijn 2006/112/EC van de Raad van de EU"
#: pretix/base/models/tax.py:231
#, python-brace-format
@@ -6360,15 +6354,11 @@ msgid ""
"Exempt based on article {article}, section ({letter}) of Council Directive "
"2006/112/EC"
msgstr ""
"Uitgesloten op basis van artikel {article}, paragraaf {letter} van de "
"richtlijn 2006/112/EC van de Raad van de EU"
#: pretix/base/models/tax.py:252
msgctxt "tax_code"
msgid "Exempt based on article 309 of Council Directive 2006/112/EC"
msgstr ""
"Uitgesloten op basis van artikel 309 van de richtlijn 2006/112/EC van de "
"Raad van de EU"
#: pretix/base/models/tax.py:254
msgctxt "tax_code"
@@ -7337,7 +7327,7 @@ msgstr "John Doe"
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:186
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:189
msgid "Attendee company"
msgstr "Bedrijf aanwezige"
msgstr "Bedrijf van gast"
#: pretix/base/pdf.py:178 pretix/base/pdf.py:336
#: pretix/base/services/tickets.py:119 pretix/control/views/pdf.py:111
@@ -7746,8 +7736,8 @@ msgid ""
"We were not able to process your request completely as the server was too "
"busy. Please try again."
msgstr ""
"We konden uw aanvraag niet verwerken omdat de server bezet was. Probeer het "
"opnieuw."
"We konden uw verzoek niet verwerken omdat de server overbelast was. Probeer "
"het opnieuw."
#: pretix/base/services/cart.py:104 pretix/presale/views/cart.py:260
msgid "You did not select any products."
@@ -15620,7 +15610,7 @@ msgstr "Het aantal keren dat ELKE van deze vouchers kan worden gebruikt."
#: pretix/control/forms/vouchers.py:347
msgid "Specific seat IDs"
msgstr "Specifieke zitplaatsnummers"
msgstr "Specifieke stoelnummers"
#: pretix/control/forms/vouchers.py:364
msgid "CSV input needs to contain a header row in the first line."
@@ -31840,7 +31830,7 @@ msgstr "Alternatief tickets"
#: pretix/plugins/ticketoutputpdf/templates/pretixplugins/ticketoutputpdf/edit.html:8
#: pretix/plugins/ticketoutputpdf/templates/pretixplugins/ticketoutputpdf/edit.html:15
msgid "Ticket layout"
msgstr "Ticket lay-out"
msgstr "Ticketlay-out"
#: pretix/plugins/ticketoutputpdf/templates/pretixplugins/ticketoutputpdf/delete.html:9
#, python-format

View File

@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-02-25 10:10+0000\n"
"PO-Revision-Date: 2025-03-12 19:00+0000\n"
"PO-Revision-Date: 2025-03-03 16:00+0000\n"
"Last-Translator: Wiktor Przybylski <wikprzybylski@gmail.com>\n"
"Language-Team: Polish <https://translate.pretix.eu/projects/pretix/pretix/pl/"
">\n"
@@ -18,7 +18,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
"|| n%100>=20) ? 1 : 2;\n"
"X-Generator: Weblate 5.10.2\n"
"X-Generator: Weblate 5.10.1\n"
#: pretix/_base_settings.py:87
msgid "English"
@@ -4312,7 +4312,7 @@ msgstr ""
#: pretix/base/models/event.py:571 pretix/base/models/organizer.py:87
msgid "The slug may only contain letters, numbers, dots and dashes."
msgstr "Slug powinien zawierać jedynie litery, cyfry, kropki lub myślniki."
msgstr "Krótka forma może zawierać tylko litery, cyfry, kropki i myślniki."
#: pretix/base/models/event.py:588 pretix/base/models/event.py:1464
msgid "Show in lists"

File diff suppressed because it is too large Load Diff

View File

@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-02-25 10:10+0000\n"
"PO-Revision-Date: 2025-03-15 20:49+0000\n"
"PO-Revision-Date: 2025-03-02 12:55+0000\n"
"Last-Translator: Kristian Feldsam <feldsam@gmail.com>\n"
"Language-Team: Slovak <https://translate.pretix.eu/projects/pretix/pretix/sk/"
">\n"
@@ -17,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
"X-Generator: Weblate 5.10.3\n"
"X-Generator: Weblate 5.10.1\n"
#: pretix/_base_settings.py:87
msgid "English"
@@ -27945,8 +27945,7 @@ msgstr ""
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_payment_form.html:26
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/pending.html:39
msgid "Reference code (important):"
msgstr ""
"Referencia platby<br><small>Poznámka alebo správa pre prijímateľa</small>:"
msgstr "Referencia platby (dôležité):"
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_confirm.html:31
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_payment_form.html:31

View File

@@ -410,7 +410,7 @@ class BankTransfer(BasePaymentProvider):
'message': email_content,
'position': None,
'recipient': email,
'invoices': [invoice.pk],
'invoices': invoice.pk,
'attach_tickets': False,
'attach_ical': False,
}

View File

@@ -38,9 +38,7 @@ from i18nfield.strings import LazyI18nString
from pretix.base.email import get_email_context
from pretix.base.i18n import language
from pretix.base.models import (
CachedFile, Checkin, Event, InvoiceAddress, Order, User,
)
from pretix.base.models import Checkin, Event, InvoiceAddress, Order, User
from pretix.base.services.mail import SendMailException, mail
from pretix.base.services.tasks import ProfiledEventTask
from pretix.celery_app import app
@@ -58,7 +56,6 @@ def send_mails_to_orders(event: Event, user: int, subject: dict, message: dict,
orders = Order.objects.filter(pk__in=objects, event=event)
subject = LazyI18nString(subject)
message = LazyI18nString(message)
attachments_for_log = [cf.filename for cf in CachedFile.objects.filter(pk__in=attachments)] if attachments else []
for o in orders:
send_to_order = recipients in ('both', 'orders')
@@ -137,11 +134,7 @@ def send_mails_to_orders(event: Event, user: int, subject: dict, message: dict,
'position': p.positionid,
'subject': format_map(subject.localize(o.locale), email_context),
'message': format_map(message.localize(o.locale), email_context),
'recipient': p.attendee_email,
'attach_tickets': attach_tickets,
'attach_ical': attach_ical,
'attach_other_files': [],
'attach_cached_files': attachments_for_log,
'recipient': p.attendee_email
}
)
except SendMailException:
@@ -169,11 +162,7 @@ def send_mails_to_orders(event: Event, user: int, subject: dict, message: dict,
data={
'subject': format_map(subject.localize(o.locale), email_context),
'message': format_map(message.localize(o.locale), email_context),
'recipient': o.email,
'attach_tickets': attach_tickets,
'attach_ical': attach_ical,
'attach_other_files': [],
'attach_cached_files': attachments_for_log,
'recipient': o.email
}
)
except SendMailException:

View File

@@ -45,28 +45,27 @@
<div lang="{{ locale }}" class="mail-preview">
<strong>{{ out.subject|safe }}</strong><br><br>
{{ out.html|safe }}
<ul class="list-unstyled">
{% if out.attachment %}
<li>
<span class="fa fa-file-o fa-fw" aria-hidden="true"></span>
<a href="{% url 'cachedfile.download' id=out.attachment.id %}" target="_blank">
{{ out.attachment.filename }}
</a>
</li>
{% endif %}
{% if form.cleaned_data.attach_tickets %}
<li>
<span class="fa fa-file-o fa-fw" aria-hidden="true"></span>
{% trans "Tickets" %}
</li>
{% endif %}
{% if form.cleaned_data.attach_ical %}
<li>
<span class="fa fa-calendar-o fa-fw" aria-hidden="true"></span>
{% trans "Attach calendar files" %}
</li>
{% endif %}
</ul>
{% if out.attachment %}
<p>
<a href="{% url 'cachedfile.download' id=out.attachment.id %}" class="btn btn-default"
target="_blank">
<span class="fa fa-file" aria-hidden="true"></span>
{{ out.attachment.filename }}
</a>
</p>
{% endif %}
{% if form.cleaned_data.attach_tickets %}
<p>
<span class="fa fa-file" aria-hidden="true"></span>
{% trans "Tickets" %}
</p>
{% endif %}
{% if form.cleaned_data.attach_ical %}
<p>
<span class="fa fa-file" aria-hidden="true"></span>
{% trans "Attach calendar files" %}
</p>
{% endif %}
</div>
{% endfor %}
</div>

View File

@@ -40,7 +40,7 @@ from django.utils.translation import get_language_info
from django_scopes import get_scope
from i18nfield.strings import LazyI18nString
from pretix.base.settings import COUNTRY_STATE_LABEL, GlobalSettingsObject
from pretix.base.settings import GlobalSettingsObject
from pretix.helpers.i18n import (
get_javascript_format_without_seconds, get_moment_locale,
)
@@ -187,7 +187,6 @@ def _default_context(request):
ctx['html_locale'] = translation.get_language_info(get_language_without_region()).get('public_code', translation.get_language())
ctx['settings'] = pretix_settings
ctx['django_settings'] = settings
ctx['COUNTRY_STATE_LABEL'] = COUNTRY_STATE_LABEL
ctx['ie_deprecation_warning'] = 'MSIE' in request.headers.get('User-Agent', '') or 'Trident/' in request.headers.get('User-Agent', '')

View File

@@ -42,7 +42,11 @@
{% if form.pos.subevent %}
<p>
<span class="fa fa-calendar" aria-hidden="true"></span>
{{ form.pos.subevent.name }} &middot; {{ form.pos.subevent.get_date_range_display_with_times_as_html }}
{{ form.pos.subevent.name }} &middot; {{ form.pos.subevent.get_date_range_display_as_html }}
{% if form.pos.event.settings.show_times %}
<span class="fa fa-clock-o" aria-hidden="true"></span>
{{ form.pos.subevent.date_from|date:"TIME_FORMAT" }}
{% endif %}
</p>
{% endif %}
{% include "pretixpresale/event/fragment_addon_choice.html" with form=form %}

View File

@@ -4,7 +4,6 @@
{% load money %}
{% load eventurl %}
{% load eventsignal %}
{% load getitem %}
{% block title %}{% trans "Review order" %}{% endblock %}
{% block content %}
<main aria-label="{% trans "Review order" %}">
@@ -93,7 +92,7 @@
<dt>{% trans "Country" %}</dt>
<dd>{{ addr.country.name }}</dd>
{% if addr.state %}
<dt>{% trans "State" context "address" as state_label %}{{ COUNTRY_STATE_LABEL|getitem:addr.country.code|default:state_label }}</dt>
<dt>{% trans "State" context "address" %}</dt>
<dd>{{ addr.state_name }}</dd>
{% endif %}
{% if request.event.settings.invoice_address_vatid and addr.vat_id %}

View File

@@ -52,7 +52,13 @@
</label>
<div class="col-md-9 form-control-text">
<ul class="addon-list">
{{ form.position.subevent.name }} &middot; {{ form.position.subevent.get_date_range_display_with_times_as_html }}
{{ form.position.subevent.name }} &middot; {{ form.position.subevent.get_date_range_display_as_html }}
{% if form.position.event.settings.show_times %}
<span data-time="{{ form.position.subevent.date_from.isoformat }}" data-timezone="{{ request.event.timezone }}">
<span class="fa fa-clock-o" aria-hidden="true"></span>
{{ form.position.subevent.date_from|date:"TIME_FORMAT" }}
</span>
{% endif %}
</ul>
</div>
</div>

View File

@@ -130,7 +130,13 @@
</label>
<div class="col-md-9 form-control-text">
<ul class="addon-list">
{{ pos.subevent.name }} &middot; {{ pos.subevent.get_date_range_display_with_times_as_html }}
{{ pos.subevent.name }} &middot; {{ pos.subevent.get_date_range_display_as_html }}
{% if pos.event.settings.show_times %}
<span data-time="{{ pos.subevent.date_from.isoformat }}" data-timezone="{{ request.event.timezone }}">
<span class="fa fa-clock-o" aria-hidden="true"></span>
{{ pos.subevent.date_from|date:"TIME_FORMAT" }}
</span>
{% endif %}
</ul>
</div>
</div>

View File

@@ -62,7 +62,12 @@
<span class="fa fa-calendar fa-fw" aria-hidden="true"></span> {{ line.subevent.name }}
<br>
<span class="text-muted" aria-hidden="true">
{{ line.subevent.get_date_range_display_with_times_as_html }}
{{ line.subevent.get_date_range_display }}
{% if event.settings.show_times %}
&middot; <span data-time="{{ line.subevent.date_from.isoformat }}" data-timezone="{{ request.event.timezone }}" data-time-short>
{{ line.subevent.get_time_range_display }}
</span>
{% endif %}
</span>
<span class="sr-only">
<time datetime="{% if event.settings.show_times %}{{ line.subevent.date_from.isoformat }}{% else %}{{ line.subevent.date_from|date:"Y-m-d" }}{% endif %}">{{ line.subevent.get_date_from_display }}</time>
@@ -195,8 +200,8 @@
<span data-toggle="tooltip" title="{% trans "Attendee address" %}">
{{ line.street|default_if_none:""|linebreaksbr }}<br>
{{ line.zipcode|default_if_none:"" }} {{ line.city|default_if_none:"" }}<br>
{% if line.state %}{{ line.state_for_address }}<br>{% endif %}
{{ line.country.name|default_if_none:"" }}
{% if line.state %}<br>{{ line.state }}{% endif %}
</span>
</dd>
{% endif %}

View File

@@ -21,7 +21,11 @@
</label>
<div class="col-md-9 form-control-text">
<ul class="addon-list">
{{ position.subevent.name }} &middot; {{ position.subevent.get_date_range_display_with_times_as_html }}
{{ position.subevent.name }} &middot; {{ position.subevent.get_date_range_display_as_html }}
{% if position.event.settings.show_times %}
<span class="fa fa-clock-o" aria-hidden="true"></span>
{{ position.subevent.date_from|date:"TIME_FORMAT" }}
{% endif %}
</ul>
</div>
</div>

View File

@@ -7,7 +7,6 @@
{% load eventurl %}
{% load phone_format %}
{% load rich_text %}
{% load getitem %}
{% block title %}
{% if "thanks" in request.GET or "paid" in request.GET %}
{% trans "Thank you!" %}
@@ -320,7 +319,7 @@
<dt>{% trans "Country" %}</dt>
<dd>{{ order.invoice_address.country.name|default:order.invoice_address.country_old }}</dd>
{% if order.invoice_address.state %}
<dt>{% trans "State" context "address" as state_label %}{{ COUNTRY_STATE_LABEL|getitem:order.invoice_address.country.code|default:state_label }}</dt>
<dt>{% trans "State" context "address" %}</dt>
<dd>{{ order.invoice_address.state_name }}</dd>
{% endif %}
{% if request.event.settings.invoice_address_vatid and order.invoice_address.vat_id %}

View File

@@ -30,24 +30,24 @@
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h2 class="panel-title">
<b>
{% if "old" in request.GET %}
{% trans "Past events" %}
{% else %}
{% trans "Upcoming events" %}
{% endif %}
</b>
</h2>
</div>
{% if filter_form.fields %}
<div class="panel-subhead">
{% include "pretixpresale/fragment_event_list_filter.html" with request=request %}
</div>
{% endif %}
{% if events %}
{% if events %}
<div class="panel panel-default">
<div class="panel-heading">
<h2 class="panel-title">
<b>
{% if "old" in request.GET %}
{% trans "Past events" %}
{% else %}
{% trans "Upcoming events" %}
{% endif %}
</b>
</h2>
</div>
{% if filter_form.fields %}
<div class="panel-subhead">
{% include "pretixpresale/fragment_event_list_filter.html" with request=request %}
</div>
{% endif %}
<div class="panel-body">
<dl class="full-width-list alternating-rows">
{% for e in events %}{% eventurl e "presale:event.index" as url %}
@@ -99,15 +99,12 @@
{% endfor %}
</dl>
</div>
<hr>
{% endif %}
<div class="panel-body">
{% if "old" in request.GET %}
<p><em>{% if not events %}{% trans "No archived events found." %} {% endif %}<a href="?{% url_replace request "old" "" %}">{% trans "Show upcoming" %}</a></em></p>
{% else %}
<p><em>{% if not events %}{% trans "No public upcoming events found." %} {% endif %}<a href="?{% url_replace request "old" "1" %}">{% trans "Show past events" %}</a></em></p>
{% endif %}
</div>
</div>
{% endif %}
{% if "old" in request.GET %}
<p><em>{% if not events %}{% trans "No archived events found." %} {% endif %}<a href="?{% url_replace request "old" "" %}">{% trans "Show upcoming" %}</a></em></p>
{% else %}
<p><em>{% if not events %}{% trans "No public upcoming events found." %} {% endif %}<a href="?{% url_replace request "old" "1" %}">{% trans "Show past events" %}</a></em></p>
{% endif %}
{% include "pretixpresale/pagination.html" %}
{% endblock %}

View File

@@ -158,13 +158,11 @@ def _item_from_post_value(request, key, value, voucher=None, voucher_ignore_if_r
return
subevent = None
prefix = ''
if key.startswith('subevent_'):
try:
parts = key.split('_', 2)
subevent = int(parts[1])
key = parts[2]
prefix = f'subevent_{subevent}_'
except ValueError:
pass
elif 'subevent' in request.POST:
@@ -177,7 +175,7 @@ def _item_from_post_value(request, key, value, voucher=None, voucher_ignore_if_r
return
parts = key.split("_")
price = request.POST.get(prefix + 'price_' + "_".join(parts[1:]), "")
price = request.POST.get('price_' + "_".join(parts[1:]), "")
if key.startswith('seat_'):
try:

View File

@@ -500,37 +500,33 @@ class EventIndex(EventViewMixin, EventListMixin, CartMixin, TemplateView):
self.subevent = None
utm_params = {k: v for k, v in request.GET.items() if k.startswith("utm_")}
pass_through_url_params = utm_params | \
{k: v for k, v in request.GET.items() if k in ("locale", "consent")} | \
({"widget_data": request.GET.get('widget_data')} if len(self.request.GET.get('widget_data', '{}')) > 3 else {})
if request.GET.get('src', '') == 'widget' and 'take_cart_id' in request.GET:
# User has clicked "Open in a new tab" link in widget
get_or_create_cart_id(request)
return redirect_to_url(eventreverse(request.event, 'presale:event.index', kwargs=kwargs) + '?' + urlencode(utm_params))
elif request.GET.get('iframe', '') == '1' and (
'take_cart_id' in request.GET or len(self.request.GET.get('widget_data', '{}')) > 3 or 'consent' in request.GET
):
# Widget just opened, and a cart already exists or we have been passed widget_data.
# Let's do a stupid redirect to check if cookies are disabled.
elif request.GET.get('iframe', '') == '1' and 'take_cart_id' in request.GET:
# Widget just opened, a cart already exists. Let's to a stupid redirect to check if cookies are disabled
get_or_create_cart_id(request)
return redirect_to_url(eventreverse(request.event, 'presale:event.index', kwargs=kwargs) + '?' + urlencode({
'require_cookie': 'true',
'cart_id': get_or_create_cart_id(request),
**pass_through_url_params,
'cart_id': request.GET.get('take_cart_id'),
**({"locale": request.GET.get('locale')} if request.GET.get('locale') else {}),
**utm_params,
}))
elif request.GET.get('iframe', '') == '1' and len(self.request.GET.get('widget_data', '{}')) > 3:
# We've been passed data from a widget, we need to create a cart session to store it.
get_or_create_cart_id(request)
elif 'require_cookie' in request.GET and settings.SESSION_COOKIE_NAME not in request.COOKIES and \
'__Host-' + settings.SESSION_COOKIE_NAME not in self.request.COOKIES:
# Cookies are in fact not supported
r = render(request, 'pretixpresale/event/cookies.html', {
'url': eventreverse(
request.event, "presale:event.index", kwargs={
'cart_namespace': kwargs.get('cart_namespace') or '',
**({"subevent": kwargs['subevent']} if kwargs.get('subevent') else {}),
}
request.event, "presale:event.index", kwargs={'cart_namespace': kwargs.get('cart_namespace') or ''}
) + "?" + urlencode({
"src": "widget",
**({"locale": request.GET.get('locale')} if request.GET.get('locale') else {}),
**({"take_cart_id": request.GET.get('cart_id')} if request.GET.get('cart_id') else {}),
**pass_through_url_params,
**utm_params,
})
})
r._csp_ignore = True

View File

@@ -388,13 +388,13 @@
}
},
"node_modules/@babel/helpers": {
"version": "7.26.10",
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.10.tgz",
"integrity": "sha512-UPYc3SauzZ3JGgj87GgZ89JVdC5dj0AoetR5Bw6wj4niittNyFh6+eOGonYvJ1ao6B8lEa3Q3klS7ADZ53bc5g==",
"version": "7.26.9",
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.9.tgz",
"integrity": "sha512-Mz/4+y8udxBKdmzt/UjPACs4G3j5SshJJEFFKxlCGPydG4JAHXxjWjAwjd09tf6oINvl1VfMJo+nB7H2YKQ0dA==",
"license": "MIT",
"dependencies": {
"@babel/template": "^7.26.9",
"@babel/types": "^7.26.10"
"@babel/types": "^7.26.9"
},
"engines": {
"node": ">=6.9.0"
@@ -1393,10 +1393,9 @@
}
},
"node_modules/@babel/runtime": {
"version": "7.26.10",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.10.tgz",
"integrity": "sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw==",
"license": "MIT",
"version": "7.26.0",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz",
"integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==",
"dependencies": {
"regenerator-runtime": "^0.14.0"
},
@@ -1437,9 +1436,9 @@
}
},
"node_modules/@babel/types": {
"version": "7.26.10",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.10.tgz",
"integrity": "sha512-emqcG3vHrpxUKTrxcblR36dcrcoRDvKmnL/dCL6ZsHaShW80qxCAcNhzQZrpeM765VzEos+xOi4s+r4IXzTwdQ==",
"version": "7.26.9",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.9.tgz",
"integrity": "sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==",
"license": "MIT",
"dependencies": {
"@babel/helper-string-parser": "^7.25.9",
@@ -4037,12 +4036,12 @@
}
},
"@babel/helpers": {
"version": "7.26.10",
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.10.tgz",
"integrity": "sha512-UPYc3SauzZ3JGgj87GgZ89JVdC5dj0AoetR5Bw6wj4niittNyFh6+eOGonYvJ1ao6B8lEa3Q3klS7ADZ53bc5g==",
"version": "7.26.9",
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.9.tgz",
"integrity": "sha512-Mz/4+y8udxBKdmzt/UjPACs4G3j5SshJJEFFKxlCGPydG4JAHXxjWjAwjd09tf6oINvl1VfMJo+nB7H2YKQ0dA==",
"requires": {
"@babel/template": "^7.26.9",
"@babel/types": "^7.26.10"
"@babel/types": "^7.26.9"
}
},
"@babel/parser": {
@@ -4659,9 +4658,9 @@
}
},
"@babel/runtime": {
"version": "7.26.10",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.10.tgz",
"integrity": "sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw==",
"version": "7.26.0",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz",
"integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==",
"requires": {
"regenerator-runtime": "^0.14.0"
}
@@ -4691,9 +4690,9 @@
}
},
"@babel/types": {
"version": "7.26.10",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.10.tgz",
"integrity": "sha512-emqcG3vHrpxUKTrxcblR36dcrcoRDvKmnL/dCL6ZsHaShW80qxCAcNhzQZrpeM765VzEos+xOi4s+r4IXzTwdQ==",
"version": "7.26.9",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.9.tgz",
"integrity": "sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==",
"requires": {
"@babel/helper-string-parser": "^7.25.9",
"@babel/helper-validator-identifier": "^7.25.9"

View File

@@ -44,10 +44,6 @@ $(function () {
);
}
if ('label' in options) {
dependent.closest(".form-group").find(".control-label").text(options.label);
}
const required = 'required' in options && options.required && isRequired && visible;
dependent.closest(".form-group").toggle(visible).toggleClass('required', required);
dependent.prop("required", required);

View File

@@ -1115,7 +1115,7 @@ var editor = {
},
_on_keydown: function (e) {
var step = editor._mm2px(e.shiftKey ? 10 : (e.altKey ? 0.1 : 1));
var step = e.shiftKey ? editor._mm2px(10) : editor._mm2px(1);
var thing = editor.fabric.getActiveObject();
if ($("#source-container").is(':visible')) {
return true;

View File

@@ -314,12 +314,6 @@ function setup_week_calendar() {
}
}
function get_label_text_for_id(id) {
return $("label[for=" + id +"]").first().contents().filter(function () {
return this.nodeType != Node.ELEMENT_NODE || !this.classList.contains("sr-only");
}).text().trim();
}
$(function () {
"use strict";
@@ -350,7 +344,7 @@ $(function () {
$("#ajaxerr").on("click", ".ajaxerr-close", ajaxErrDialog.hide);
// Handlers for "Copy answers from above" buttons
// Copy answers
$(".js-copy-answers").click(function (e) {
e.preventDefault();
e.stopPropagation();
@@ -378,37 +372,44 @@ $(function () {
copy_answers(elements, answers);
return false;
});
// Automatically copy answers from invoice to first attendee
var attendee_address_fields = $("input[id*=attendee_name_parts_], input[id*=attendee_email], " +
".questions-form input[id$=company], .questions-form input[id$=street], " +
".questions-form input[id$=zipcode], .questions-form input[id$=city]");
function copy_to_first_ticket () {
var source = this;
var source_label = get_label_text_for_id(source.id);
var $first_ticket_form = $(".questions-form").first().find("[data-addonidx=0]");
var $candidates = $first_ticket_form.find(source.tagName + ":not([type='checkbox'], [type='radio'])");
var $match = $candidates.filter(function() {
return (
this.id.endsWith(source.id.substring(3))
|| (this.placeholder && this.placeholder === source.placeholder)
|| (this.placeholder && this.placeholder === source_label)
|| (source_label && get_label_text_for_id(this.id) === source_label)
);
}).first();
$match.val(this.value).trigger("change");
}
function valueIsEmpty(el) { return !el.value; }
if (attendee_address_fields.toArray().every(valueIsEmpty)) {
var invoice_address_fields = $("select[id^=id_name_parts], input[id^=id_name_parts_], #id_email, #id_street, " +
"#id_company, #id_zipcode, #id_city, #id_country, #id_state");
invoice_address_fields.on("change", copy_to_first_ticket).trigger("change");
attendee_address_fields.one("input", function () {
invoice_address_fields.off("change", copy_to_first_ticket);
});
}
var copy_to_first_ticket = true;
var attendee_address_fields = $("input[id*=attendee_name_parts_], input[id*=attendee_email], .questions-form" +
" input[id$=company], .questions-form[id$=street], .questions-form input[id$=zipcode], .questions-form" +
" input[id$=city]");
attendee_address_fields.each(function () {
if ($(this).val()) {
copy_to_first_ticket = false;
}
})
$("select[id^=id_name_parts], input[id^=id_name_parts_], #id_email, #id_street, #id_company, #id_zipcode," +
" #id_city, #id_country, #id_state").change(function () {
if (copy_to_first_ticket) {
var $first_ticket_form = $(".questions-form").first().find("[data-addonidx=0]");
$first_ticket_form.find("[id$=" + this.id.substring(3) + "]").val(this.value);
if (this.placeholder) {
$first_ticket_form.find("[placeholder='" + CSS.escape(this.placeholder) + "']").val(this.value);
}
var label = $("label[for=" + this.id +"]").first().contents().filter(function () {
return this.nodeType != Node.ELEMENT_NODE || !this.classList.contains("sr-only");
}).text().trim();
if (label) {
// match to placeholder and label
$first_ticket_form.find("[placeholder='" + CSS.escape(label) + "']").val(this.value);
var v = this.value;
$first_ticket_form.find("label").each(function() {
var text = $(this).first().contents().filter(function () {
return this.nodeType != Node.ELEMENT_NODE || !this.classList.contains("sr-only");
}).text().trim();
if (text == label) {
$("#" + this.getAttribute("for")).val(v);
}
});
}
}
}).trigger("change");
attendee_address_fields.change(function () {
copy_to_first_ticket = false;
});
questions_init_profiles($("body"));
if (sessionStorage) {
@@ -532,8 +533,8 @@ $(function () {
form_handlers($("body"));
var local_tz = moment.tz.guess()
$("span[data-timezone], small[data-timezone], time[data-timezone]").each(function() {
var t = moment.tz($(this).attr("datetime") || $(this).attr("data-time"), $(this).attr("data-timezone"))
$("span[data-timezone], small[data-timezone]").each(function() {
var t = moment.tz($(this).attr("data-time"), $(this).attr("data-timezone"))
var tz = moment.tz.zone($(this).attr("data-timezone"))
var tpl = '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner text-nowrap"></div></div>';
@@ -543,7 +544,6 @@ $(function () {
});
if (t.tz(tz.name).format() !== t.tz(local_tz).format()) {
var $add = $("<span>")
$add.append(" ")
$add.append($("<span>").addClass("fa fa-globe"))
if ($(this).is("[data-time-short]")) {
$add.append($("<em>").text(" " + t.tz(local_tz).format($("body").attr("data-timeformat"))))

View File

@@ -765,11 +765,41 @@ var shared_methods = {
redeem: function (event) {
if (this.$root.useIframe) {
event.preventDefault();
this.voucher_open(this.voucher);
} else {
if (this.$root.additionalURLParams) {
var params = new URLSearchParams(this.$root.additionalURLParams);
for (var [key, value] of params.entries()) {
if (!event.target.form.elements[key]) {
var input = document.createElement("input");
input.type = "hidden";
input.name = key;
input.value = value;
event.target.form.appendChild(input);
}
}
}
return;
}
var redirect_url = this.$root.voucherFormTarget + '&voucher=' + encodeURIComponent(this.voucher) + '&subevent=' + this.$root.subevent;
if (this.$root.widget_data) {
redirect_url += '&widget_data=' + encodeURIComponent(this.$root.widget_data_json);
}
if (this.$root.additionalURLParams) {
redirect_url += '&' + this.$root.additionalURLParams;
}
redirect_url += this.$root.consent_parameter;
this.$root.overlay.frame_src = redirect_url;
},
voucher_open: function (voucher) {
var redirect_url = this.$root.voucherFormTarget + '&voucher=' + encodeURIComponent(voucher);
var redirect_url;
redirect_url = this.$root.voucherFormTarget + '&voucher=' + encodeURIComponent(voucher);
if (this.$root.widget_data) {
redirect_url += '&widget_data=' + encodeURIComponent(this.$root.widget_data_json);
}
if (this.$root.additionalURLParams) {
redirect_url += '&' + this.$root.additionalURLParams;
}
redirect_url += this.$root.consent_parameter;
if (this.$root.useIframe) {
this.$root.overlay.frame_src = redirect_url;
} else {
@@ -1045,7 +1075,10 @@ Vue.component('pretix-widget-event-form', {
+ '<div class="pretix-widget-voucher-input-wrap">'
+ '<input class="pretix-widget-voucher-input" ref="voucherinput" type="text" v-model="$parent.voucher" name="voucher" placeholder="'+strings.voucher_code+'">'
+ '</div>'
+ '<input type="hidden" v-for="p in hiddenParams" :name="p[0]" :value="p[1]" />'
+ '<input type="hidden" name="subevent" :value="$root.subevent" />'
+ '<input type="hidden" name="widget_data" :value="$root.widget_data_json" />'
+ '<input v-if="$root.consent_parameter_value" type="hidden" name="consent" :value="$root.consent_parameter_value" />'
+ '<input type="hidden" name="locale" value="' + lang + '" />'
+ '<div class="pretix-widget-voucher-button-wrap">'
+ '<button @click="$parent.redeem">' + strings.redeem + '</button>'
+ '</div>'
@@ -1103,13 +1136,7 @@ Vue.component('pretix-widget-event-form', {
} else {
return strings.buy;
}
},
hiddenParams: function () {
var params = new URL(this.$root.voucherFormTarget).searchParams;
params.delete("iframe");
params.delete("take_cart_id");
return [...params.entries()];
},
}
},
methods: {
focus_voucher_field: function() {
@@ -1946,9 +1973,6 @@ var shared_root_computed = {
if (this.subevent) {
form_target += "&subevent=" + this.subevent;
}
if (this.$root.widget_data) {
form_target += '&widget_data=' + encodeURIComponent(this.$root.widget_data_json);
}
form_target += this.$root.consent_parameter;
if (this.$root.additionalURLParams) {
form_target += '&' + this.$root.additionalURLParams;

View File

@@ -83,7 +83,7 @@
position: relative;
padding-left: 1.4em;
text-indent: 0;
& > .fa, & > svg, & > dd > .fa, & > dd > svg {
.fa, svg {
position: absolute;
left: 0;
top: .22em;

View File

@@ -145,11 +145,6 @@ article.item-with-variations .product-row:last-child:after {
margin-bottom: 0;
}
.panel > hr {
margin: 0;
border-top: 1px solid $table-border-color;
}
.product-row {
padding: 1.25*$line-height-computed 0;

View File

@@ -413,6 +413,7 @@ details.details-open .panel-title::before {
}
.panel-subhead {
margin-bottom: 15px;
padding: 15px;
background: $table-bg-accent;
border-bottom: 1px solid $table-border-color;

View File

@@ -35,7 +35,6 @@
import datetime
import sys
import time
import zoneinfo
from datetime import date, timedelta
from decimal import Decimal
@@ -2459,57 +2458,6 @@ class EventTest(TestCase):
item.save()
assert Event.annotated(Event.objects, 'web').first().active_quotas == []
@classscope(attr='organizer')
def test_date_range_display(self):
tz = zoneinfo.ZoneInfo("Europe/Berlin")
sets = (
(
datetime.datetime(2025, 3, 9, 21, 0, 0, tzinfo=tz),
datetime.datetime(2025, 3, 9, 22, 0, 0, tzinfo=tz),
'Sun, March 9th, 2025',
'<time datetime="2025-03-09">Sun, March 9th, 2025</time>',
'Sun, March 9th, 2025 20:0021:00',
'<time datetime="2025-03-09">Sun, March 9th, 2025</time> '
'<time datetime="2025-03-09T21:00:00+01:00" data-timezone="UTC" data-time-short>20:0021:00</time>'
),
(
datetime.datetime(2025, 3, 9, 21, 0, 0, tzinfo=tz),
datetime.datetime(2025, 3, 10, 3, 0, 0, tzinfo=tz),
'March 9th 10th, 2025',
'<time datetime="2025-03-09">March 9th</time> <time datetime="2025-03-10">10th, 2025</time>',
'March 9th 10th, 2025 20:0002:00',
'<time datetime="2025-03-09">March 9th</time> <time datetime="2025-03-10">10th, 2025</time> '
'<time datetime="2025-03-09T21:00:00+01:00" data-timezone="UTC" data-time-short>20:0002:00</time>'
),
(
datetime.datetime(2025, 3, 9, 21, 0, 0, tzinfo=tz),
datetime.datetime(2025, 3, 12, 14, 0, 0, tzinfo=tz),
'March 9th 12th, 2025',
'<time datetime="2025-03-09">March 9th</time> <time datetime="2025-03-12">12th, 2025</time>',
'March 9th 12th, 2025',
'<time datetime="2025-03-09">March 9th</time> <time datetime="2025-03-12">12th, 2025</time>',
),
(
datetime.datetime(2025, 3, 9, 21, 0, 0, tzinfo=tz),
None,
'Sun, March 9th, 2025',
'<time datetime="2025-03-09">Sun, March 9th, 2025</time>',
'Sun, March 9th, 2025 20:00',
'<time datetime="2025-03-09">Sun, March 9th, 2025</time> '
'<time datetime="2025-03-09T21:00:00+01:00" data-timezone="UTC" data-time-short>20:00</time>'
),
)
for i, (df, dt, expected, expected_html, expected_with_times, expected_with_times_html) in enumerate(sets):
event = Event.objects.create(
organizer=self.organizer, name='Dummy', slug=f'dummy{i}',
date_from=df, date_to=dt,
)
assert event.get_date_range_display() == expected
assert event.get_date_range_display(as_html=True) == expected_html
assert event.get_date_range_display(try_to_show_times=True) == expected_with_times
assert event.get_date_range_display(try_to_show_times=True, as_html=True) == expected_with_times_html
class SubEventTest(TestCase):
def setUp(self):