mirror of
https://github.com/pretix/pretix.git
synced 2026-05-07 15:34:02 +00:00
Add locations to program times (Z#23221129)
Add location for program time slots and extend .ical and PDF placeholder
This commit is contained in:
@@ -191,7 +191,7 @@ class InlineItemAddOnSerializer(serializers.ModelSerializer):
|
||||
class InlineItemProgramTimeSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = ItemProgramTime
|
||||
fields = ('start', 'end')
|
||||
fields = ('start', 'end', 'location')
|
||||
|
||||
|
||||
class ItemBundleSerializer(serializers.ModelSerializer):
|
||||
@@ -222,7 +222,7 @@ class ItemBundleSerializer(serializers.ModelSerializer):
|
||||
class ItemProgramTimeSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = ItemProgramTime
|
||||
fields = ('id', 'start', 'end')
|
||||
fields = ('id', 'start', 'end', 'location')
|
||||
|
||||
def validate(self, data):
|
||||
data = super().validate(data)
|
||||
|
||||
19
src/pretix/base/migrations/0299_itemprogramtime_location.py
Normal file
19
src/pretix/base/migrations/0299_itemprogramtime_location.py
Normal file
@@ -0,0 +1,19 @@
|
||||
# Generated by Django 4.2.27 on 2026-01-21 12:06
|
||||
|
||||
import i18nfield.fields
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("pretixbase", "0298_pluggable_permissions"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="itemprogramtime",
|
||||
name="location",
|
||||
field=i18nfield.fields.I18nTextField(max_length=200, null=True),
|
||||
)
|
||||
]
|
||||
@@ -2306,10 +2306,17 @@ class ItemProgramTime(models.Model):
|
||||
:type start: datetime
|
||||
:param end: The date and time this program time ends
|
||||
:type end: datetime
|
||||
:param location: venue
|
||||
:type location: str
|
||||
"""
|
||||
item = models.ForeignKey('Item', related_name='program_times', on_delete=models.CASCADE)
|
||||
start = models.DateTimeField(verbose_name=_("Start"))
|
||||
end = models.DateTimeField(verbose_name=_("End"))
|
||||
location = I18nTextField(
|
||||
null=True, blank=True,
|
||||
max_length=200,
|
||||
verbose_name=_("Location"),
|
||||
)
|
||||
|
||||
def clean(self):
|
||||
if hasattr(self, 'item') and self.item and self.item.event.has_subevents:
|
||||
|
||||
@@ -498,9 +498,9 @@ DEFAULT_VARIABLES = OrderedDict((
|
||||
) if op.valid_until else ""
|
||||
}),
|
||||
("program_times", {
|
||||
"label": _("Program times: date and time"),
|
||||
"label": _("Program times"),
|
||||
"editor_sample": _(
|
||||
"2017-05-31 10:00 – 12:00\n2017-05-31 14:00 – 16:00\n2017-05-31 14:00 – 2017-06-01 14:00"),
|
||||
"2017-05-31 10:00 – 12:00, Room 1\n2017-05-31 14:00 – 16:00, Room 2\n2017-05-31 14:00 – 2017-06-01 14:00, Building A"),
|
||||
"evaluate": lambda op, order, ev: get_program_times(op, ev)
|
||||
}),
|
||||
("medium_identifier", {
|
||||
@@ -748,13 +748,19 @@ def get_seat(op: OrderPosition):
|
||||
|
||||
|
||||
def get_program_times(op: OrderPosition, ev: Event):
|
||||
return '\n'.join([
|
||||
datetimerange(
|
||||
pt.start.astimezone(ev.timezone),
|
||||
pt.end.astimezone(ev.timezone),
|
||||
as_html=False
|
||||
) for pt in op.item.program_times.all()
|
||||
])
|
||||
ptstr = []
|
||||
for pt in op.item.program_times.all():
|
||||
ptstr.append([
|
||||
datetimerange(
|
||||
pt.start.astimezone(ev.timezone),
|
||||
pt.end.astimezone(ev.timezone),
|
||||
as_html=False
|
||||
),
|
||||
(', ' + ', '.join(
|
||||
l.strip() for l in str(pt.location).splitlines() if l.strip())
|
||||
) if str(pt.location).strip() else ''
|
||||
])
|
||||
return '\n'.join(''.join(l) for l in ptstr)
|
||||
|
||||
|
||||
def generate_compressed_addon_list(op, order, event, only_checked_in=False):
|
||||
|
||||
@@ -574,7 +574,7 @@ class ItemCreateForm(I18nModelForm):
|
||||
instance.bundles.create(bundled_item=b.bundled_item, bundled_variation=b.bundled_variation,
|
||||
count=b.count, designated_price=b.designated_price)
|
||||
for pt in self.cleaned_data['copy_from'].program_times.all():
|
||||
instance.program_times.create(start=pt.start, end=pt.end)
|
||||
instance.program_times.create(start=pt.start, end=pt.end, location=pt.location)
|
||||
|
||||
item_copy_data.send(sender=self.event, source=self.cleaned_data['copy_from'], target=instance)
|
||||
|
||||
@@ -1354,6 +1354,10 @@ class ItemProgramTimeForm(I18nModelForm):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.fields['end'].widget.attrs['data-date-after'] = '#id_{prefix}-start_0'.format(prefix=self.prefix)
|
||||
self.fields['location'].widget.attrs['rows'] = '3'
|
||||
self.fields['location'].widget.attrs['placeholder'] = _(
|
||||
'Sample Conference Center, Heidelberg, Germany'
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = ItemProgramTime
|
||||
@@ -1361,6 +1365,7 @@ class ItemProgramTimeForm(I18nModelForm):
|
||||
fields = [
|
||||
'start',
|
||||
'end',
|
||||
'location'
|
||||
]
|
||||
field_classes = {
|
||||
'start': forms.SplitDateTimeField,
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
{% bootstrap_form_errors form %}
|
||||
{% bootstrap_field form.start layout="control" %}
|
||||
{% bootstrap_field form.end layout="control" %}
|
||||
{% bootstrap_field form.location layout="control" %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
@@ -59,6 +60,7 @@
|
||||
<div class="panel-body form-horizontal">
|
||||
{% bootstrap_field formset.empty_form.start layout="control" %}
|
||||
{% bootstrap_field formset.empty_form.end layout="control" %}
|
||||
{% bootstrap_field formset.empty_form.location layout="control" %}
|
||||
</div>
|
||||
</div>
|
||||
{% endescapescript %}
|
||||
|
||||
@@ -153,7 +153,7 @@ def get_private_icals(event, positions):
|
||||
# Actual ical organizer field is not useful since it will cause "your invitation was accepted" emails to the organizer
|
||||
descr.append(_('Organizer: {organizer}').format(organizer=event.organizer.name))
|
||||
description = '\n'.join(descr)
|
||||
location = None
|
||||
location = ", ".join(l.strip() for l in str(pt.location).splitlines() if l.strip())
|
||||
dtstart = pt.start.astimezone(tz)
|
||||
dtend = pt.end.astimezone(tz)
|
||||
uid = 'pretix-{}-{}-{}-{}@{}'.format(
|
||||
|
||||
Reference in New Issue
Block a user