Compare commits

..

1 Commits

Author SHA1 Message Date
Raphael Michel
5d22fa1755 Webhooks: Allow longer URLs (fixes #5443) 2025-11-14 18:40:39 +01:00
18 changed files with 75 additions and 82 deletions

View File

@@ -5,7 +5,6 @@ Resource description
--------------------
Program times for products (items) that can be set in addition to event times, e.g. to display seperate schedules within an event.
Note that ``program_times`` are not available for items inside event series.
The program times resource contains the following public fields:
.. rst-class:: rest-resource-table

View File

@@ -142,7 +142,6 @@ variations list of objects A list with o
program_times list of objects A list with one object for each program time of this item.
Can be empty. Only writable during creation,
use separate endpoint to modify this later.
Not available for items in event series.
├ id integer Internal ID of the variation
├ value multi-lingual string The "name" of the variation
├ default_price money (string) The price set directly for this variation or ``null``
@@ -244,8 +243,6 @@ Also note that ``variations``, ``bundles``, ``addons`` and ``program_times`` ar
bundles, add-ons and program times please use the dedicated nested endpoints. By design this endpoint does not support ``PATCH`` and ``PUT``
with nested ``variations``, ``bundles``, ``addons`` and/or ``program_times``.
``program_times`` is not available to items in event series.
Endpoints
---------

View File

@@ -0,0 +1,23 @@
# Generated by Django 4.2.24 on 2025-11-14 16:21
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("pretixapi", "0013_alter_webhookcallretry_retry_not_before"),
]
operations = [
migrations.AlterField(
model_name="webhook",
name="target_url",
field=models.URLField(max_length=1024),
),
migrations.AlterField(
model_name="webhookcall",
name="target_url",
field=models.URLField(max_length=1024),
),
]

View File

@@ -114,7 +114,7 @@ class OAuthRefreshToken(AbstractRefreshToken):
class WebHook(models.Model):
organizer = models.ForeignKey('pretixbase.Organizer', on_delete=models.CASCADE, related_name='webhooks')
enabled = models.BooleanField(default=True, verbose_name=_("Enable webhook"))
target_url = models.URLField(verbose_name=_("Target URL"), max_length=255)
target_url = models.URLField(verbose_name=_("Target URL"), max_length=1024)
all_events = models.BooleanField(default=True, verbose_name=_("All events (including newly created ones)"))
limit_events = models.ManyToManyField('pretixbase.Event', verbose_name=_("Limit to events"), blank=True)
comment = models.CharField(verbose_name=_("Comment"), max_length=255, null=True, blank=True)
@@ -140,7 +140,7 @@ class WebHookEventListener(models.Model):
class WebHookCall(models.Model):
webhook = models.ForeignKey('WebHook', on_delete=models.CASCADE, related_name='calls')
datetime = models.DateTimeField(auto_now_add=True)
target_url = models.URLField(max_length=255)
target_url = models.URLField(max_length=1024)
action_type = models.CharField(max_length=255)
is_retry = models.BooleanField(default=False)
execution_time = models.FloatField(null=True)

View File

@@ -241,12 +241,6 @@ class ItemProgramTimeSerializer(serializers.ModelSerializer):
if start > end:
raise ValidationError(_("The program end must not be before the program start."))
event = self.context['event']
if event.has_subevents:
raise ValidationError({
_("You cannot use program times on an event series.")
})
return data

View File

@@ -40,7 +40,7 @@ from django_filters.rest_framework import DjangoFilterBackend, FilterSet
from django_scopes import scopes_disabled
from rest_framework import viewsets
from rest_framework.decorators import action
from rest_framework.exceptions import PermissionDenied, ValidationError
from rest_framework.exceptions import PermissionDenied
from rest_framework.response import Response
from pretix.api.pagination import TotalOrderingFilter
@@ -293,8 +293,6 @@ class ItemProgramTimeViewSet(viewsets.ModelViewSet):
return get_object_or_404(Item, pk=self.kwargs['item'], event=self.request.event)
def get_queryset(self):
if self.request.event.has_subevents:
raise ValidationError('You cannot use program times on an event series.')
return self.item.program_times.all()
def get_serializer_context(self):

View File

@@ -610,7 +610,7 @@ class OrderListExporter(MultiSheetListExporter):
headers.append(_('Attendee name') + ': ' + str(label))
headers += [
_('Attendee email'),
_('Attendee company'),
_('Company'),
_('Address'),
_('ZIP code'),
_('City'),
@@ -650,7 +650,7 @@ class OrderListExporter(MultiSheetListExporter):
options[q.pk].append(o)
headers.append(str(q.question))
headers += [
_('Invoice address company'),
_('Company'),
_('Invoice address name'),
]
if name_scheme and len(name_scheme['fields']) > 1:

View File

@@ -990,11 +990,10 @@ class Event(EventMixin, LoggedModel):
ia.bundled_variation = variation_map[ia.bundled_variation.pk]
ia.save(force_insert=True)
if not self.has_subevents and not other.has_subevents:
for ipt in ItemProgramTime.objects.filter(item__event=other).prefetch_related('item'):
ipt.pk = None
ipt.item = item_map[ipt.item.pk]
ipt.save(force_insert=True)
for ipt in ItemProgramTime.objects.filter(item__event=other).prefetch_related('item'):
ipt.pk = None
ipt.item = item_map[ipt.item.pk]
ipt.save(force_insert=True)
quota_map = {}
for q in Quota.objects.filter(event=other, subevent__isnull=True).prefetch_related('items', 'variations'):

View File

@@ -2311,8 +2311,6 @@ class ItemProgramTime(models.Model):
end = models.DateTimeField(verbose_name=_("End"))
def clean(self):
if self.item.event.has_subevents:
raise ValidationError(_("You cannot use program times on an event series."))
self.clean_start_end(start=self.start, end=self.end)
super().clean()

View File

@@ -374,13 +374,6 @@ class EventUpdateForm(I18nModelForm):
super().__init__(*args, **kwargs)
if not self.change_slug:
self.fields['slug'].widget.attrs['readonly'] = 'readonly'
if self.instance.orders.exists():
self.fields['currency'].disabled = True
self.fields['currency'].help_text = _(
'The currency cannot be changed because orders already exist.'
)
self.fields['location'].widget.attrs['rows'] = '3'
self.fields['location'].widget.attrs['placeholder'] = _(
'Sample Conference Center\nHeidelberg, Germany'

View File

@@ -858,58 +858,50 @@ class ReportExporter(ReportlabExportMixin, BaseExporter):
for c in currencies:
c_head = f" [{c}]" if len(currencies) > 1 else ""
s = self._table_transactions(form_data, c)
if s:
story += [
Spacer(0, 3 * mm),
FontFallbackParagraph(_("Orders") + c_head, style_h2),
Spacer(0, 3 * mm),
*s
]
story += [
Spacer(0, 3 * mm),
FontFallbackParagraph(_("Orders") + c_head, style_h2),
Spacer(0, 3 * mm),
*self._table_transactions(form_data, c),
]
for c in currencies:
c_head = f" [{c}]" if len(currencies) > 1 else ""
s = self._table_payments(form_data, c)
if s:
story += [
Spacer(0, 8 * mm),
FontFallbackParagraph(_("Payments") + c_head, style_h2),
Spacer(0, 3 * mm),
*s
]
story += [
Spacer(0, 8 * mm),
FontFallbackParagraph(_("Payments") + c_head, style_h2),
Spacer(0, 3 * mm),
*self._table_payments(form_data, c),
]
for c in currencies:
c_head = f" [{c}]" if len(currencies) > 1 else ""
s = self._table_open_items(form_data, c)
if s:
story += [
Spacer(0, 8 * mm),
KeepTogether(
[
FontFallbackParagraph(_("Open items") + c_head, style_h2),
Spacer(0, 3 * mm),
*s
]
),
]
story += [
Spacer(0, 8 * mm),
KeepTogether(
[
FontFallbackParagraph(_("Open items") + c_head, style_h2),
Spacer(0, 3 * mm),
*self._table_open_items(form_data, c),
]
),
]
if (
self.is_multievent
and self.events.count() == self.organizer.events.count()
):
for c in currencies:
c_head = f" [{c}]" if len(currencies) > 1 else ""
s = self._table_gift_cards(form_data, c)
if s:
story += [
Spacer(0, 8 * mm),
KeepTogether(
[
FontFallbackParagraph(_("Gift cards") + c_head, style_h2),
Spacer(0, 3 * mm),
*s,
]
),
]
story += [
Spacer(0, 8 * mm),
KeepTogether(
[
FontFallbackParagraph(_("Gift cards") + c_head, style_h2),
Spacer(0, 3 * mm),
*self._table_gift_cards(form_data, c),
]
),
]
doc.build(story, canvasmaker=self.canvas_class(doc))
f.seek(0)

View File

@@ -23,7 +23,7 @@
{% else %}
<p>{% blocktrans trimmed %}
After you submitted your order, we will redirect you to the payment service provider to complete your payment.
You will then be redirected back here.
You will then be redirected back here to get your tickets.
{% endblocktrans %}</p>
<dl class="dl-horizontal">
<dt>{% trans "Payment method" %}</dt>

View File

@@ -6,5 +6,5 @@
{% bootstrap_form form layout='horizontal' %}
<p class="help-block">{% blocktrans trimmed %}
After you submitted your order, we will redirect you to the payment service provider to complete your payment.
You will then be redirected back here.
You will then be redirected back here to get your tickets.
{% endblocktrans %}</p>

View File

@@ -11,8 +11,8 @@
<p class="help-block">
{% blocktrans trimmed %}
After you submitted your order, we will redirect you to the payment service provider to complete your payment.
You will then be redirected back here.
After you submitted your order, we will redirect you to the payment service provider to complete your
payment. You will then be redirected back here to get your tickets.
{% endblocktrans %}
</p>

View File

@@ -4,5 +4,5 @@
{% endif %}
<p class="help-block">{% blocktrans trimmed %}
After you submitted your order, we will redirect you to the payment service provider to complete your payment.
You will then be redirected back here.
You will then be redirected back here to get your tickets.
{% endblocktrans %}</p>

View File

@@ -88,7 +88,7 @@
</p>
{% endif %}
</div>
{% elif not can_download and plugins_allow_ticket_download and ticket_download_date and event.settings.ticket_download %}
{% elif not can_download and plugins_allow_ticket_download and ticket_download_date %}
{% if order.status == 'p' %}
<div class="alert alert-info info-download">
{% blocktrans trimmed with date=ticket_download_date|date:"SHORT_DATE_FORMAT" %}

View File

@@ -689,7 +689,7 @@ class EventIndex(EventViewMixin, EventListMixin, CartMixin, TemplateView):
self._set_month_year()
tz = self.request.event.timezone
_, ndays = calendar.monthrange(self.year, self.month)
before = datetime(self.year, self.month, 1, 23, 59, 59, tzinfo=tz) - timedelta(days=1)
before = datetime(self.year, self.month, 1, 0, 0, 0, tzinfo=tz) - timedelta(days=1)
after = datetime(self.year, self.month, ndays, 0, 0, 0, tzinfo=tz) + timedelta(days=1)
if self.request.event.settings.event_calendar_future_only:
@@ -750,7 +750,7 @@ class EventIndex(EventViewMixin, EventListMixin, CartMixin, TemplateView):
tz = self.request.event.timezone
week = isoweek.Week(self.year, self.week)
before = datetime(
week.monday().year, week.monday().month, week.monday().day, 23, 59, 59, tzinfo=tz
week.monday().year, week.monday().month, week.monday().day, 0, 0, 0, tzinfo=tz
) - timedelta(days=1)
after = datetime(
week.sunday().year, week.sunday().month, week.sunday().day, 0, 0, 0, tzinfo=tz

View File

@@ -768,7 +768,7 @@ class CalendarView(OrganizerViewMixin, EventListMixin, TemplateView):
raise Http404()
tz = get_current_timezone()
before = datetime(self.year, self.month, 1, 23, 59, 59, tzinfo=tz) - timedelta(days=1)
before = datetime(self.year, self.month, 1, 0, 0, 0, tzinfo=tz) - timedelta(days=1)
after = datetime(self.year, self.month, ndays, 0, 0, 0, tzinfo=tz) + timedelta(days=1)
ctx['date'] = date(self.year, self.month, 1)
@@ -854,7 +854,7 @@ class WeekCalendarView(OrganizerViewMixin, EventListMixin, TemplateView):
tz = get_current_timezone()
week = isoweek.Week(self.year, self.week)
before = datetime(
week.monday().year, week.monday().month, week.monday().day, 23, 59, 59, tzinfo=tz,
week.monday().year, week.monday().month, week.monday().day, 0, 0, 0, tzinfo=tz,
) - timedelta(days=1)
after = datetime(
week.sunday().year, week.sunday().month, week.sunday().day, 0, 0, 0, tzinfo=tz,
@@ -1001,7 +1001,7 @@ class DayCalendarView(OrganizerViewMixin, EventListMixin, TemplateView):
tz = get_current_timezone()
before = datetime(
self.date.year, self.date.month, self.date.day, 23, 59, 59, tzinfo=tz,
self.date.year, self.date.month, self.date.day, 0, 0, 0, tzinfo=tz,
) - timedelta(days=1)
after = datetime(
self.date.year, self.date.month, self.date.day, 0, 0, 0, tzinfo=tz,