manager: configure custom fields on event (#63287)

This commit is contained in:
Lauréline Guérin 2022-04-05 12:04:09 +02:00
parent 4ceb16a8e1
commit 7cd25676fc
No known key found for this signature in database
GPG Key ID: 1FAB9B9B4F93D473
2 changed files with 125 additions and 5 deletions

View File

@ -299,6 +299,24 @@ class EventForm(NewEventForm):
self.fields[field].help_text = _(
'This field cannot be modified because some recurrences have bookings attached to them.'
)
if self.instance.agenda.events_type and not self.instance.primary_event:
field_classes = {
'text': forms.CharField,
'textarea': forms.CharField,
'bool': forms.NullBooleanField,
}
widget_classes = {
'textarea': forms.widgets.Textarea,
}
for custom_field in self.instance.agenda.events_type.get_custom_fields():
field_class = field_classes[custom_field['field_type']]
field_name = 'custom_field_%s' % custom_field['varname']
self.fields[field_name] = field_class(
label=custom_field['label'],
required=False,
initial=self.instance.custom_fields.get(custom_field['varname']),
widget=widget_classes.get(custom_field['field_type']),
)
if self.instance.primary_event:
for field in (
'slug',
@ -325,6 +343,15 @@ class EventForm(NewEventForm):
):
raise ValidationError(_('Bookings exist after this date.'))
if self.instance.agenda.events_type and self.instance.primary_event is None:
custom_fields = {}
for custom_field in self.instance.agenda.events_type.get_custom_fields():
field_name = 'custom_field_%s' % custom_field['varname']
custom_fields[custom_field['varname']] = self.cleaned_data.get(field_name)
if field_name in self.cleaned_data:
del self.cleaned_data[field_name]
self.cleaned_data['custom_fields'] = custom_fields
def save(self, *args, **kwargs):
with self.instance.update_recurrences(
self.changed_data,
@ -332,7 +359,10 @@ class EventForm(NewEventForm):
self.protected_fields,
list(self.protected_fields) + ['recurrence_end_date', 'frequency'],
):
super(NewEventForm, self).save(*args, **kwargs)
super(NewEventForm, self).save(commit=False, *args, **kwargs)
if 'custom_fields' in self.cleaned_data:
self.instance.custom_fields = self.cleaned_data['custom_fields']
self.instance.save()
return self.instance

View File

@ -17,6 +17,7 @@ from chrono.agendas.models import (
Booking,
Desk,
Event,
EventsType,
Subscription,
)
from tests.utils import login
@ -25,15 +26,17 @@ pytestmark = pytest.mark.django_db
def test_add_event(app, admin_user):
agenda = Agenda(label='Foo bar')
agenda.maximal_booking_delay = 0
agenda.save()
events_type = EventsType.objects.create(
label='Foo', custom_fields=[{'varname': 'foo', 'label': 'Foo', 'field_type': 'text'}]
)
agenda = Agenda.objects.create(label='Foo bar', maximal_booking_delay=0, events_type=events_type)
Desk.objects.create(agenda=agenda, slug='_exceptions_holder')
app = login(app)
resp = app.get('/manage/agendas/%s/settings' % agenda.id, status=200)
assert "This agenda doesn't have any event yet." in resp.text
year = now().year + 1
resp = resp.click('New Event')
assert 'custom_field_foo' not in resp.context['form'].fields
resp.form['start_datetime_0'] = '%s-02-15' % year
resp.form['start_datetime_1'] = '17:00'
resp.form['places'] = 10
@ -271,10 +274,88 @@ def test_edit_event_as_manager(app, manager_user):
assert event.publication_datetime is None
def test_edit_event_with_custom_fields(app, admin_user):
events_type = EventsType.objects.create(
label='Foo',
custom_fields=[
{'varname': 'text', 'label': 'Text', 'field_type': 'text'},
{'varname': 'textarea', 'label': 'TextArea', 'field_type': 'textarea'},
{'varname': 'bool', 'label': 'Bool', 'field_type': 'bool'},
],
)
agenda = Agenda.objects.create(label='Foo', kind='events')
event = Event.objects.create(agenda=agenda, start_datetime=now(), places=10)
app = login(app)
resp = app.get('/manage/agendas/%s/events/%s/edit' % (agenda.pk, event.pk))
assert 'custom_field_text' not in resp.context['form'].fields
assert 'custom_field_textarea' not in resp.context['form'].fields
assert 'custom_field_bool' not in resp.context['form'].fields
agenda.events_type = events_type
agenda.save()
resp = app.get('/manage/agendas/%s/events/%s/edit' % (agenda.pk, event.pk))
assert 'custom_field_text' in resp.context['form'].fields
assert 'custom_field_textarea' in resp.context['form'].fields
assert 'custom_field_bool' in resp.context['form'].fields
resp.form.submit().follow()
event.refresh_from_db()
assert event.custom_fields == {
'text': '',
'textarea': '',
'bool': None,
}
resp = app.get('/manage/agendas/%s/events/%s/edit' % (agenda.pk, event.pk))
resp.form['custom_field_text'] = 'foo'
resp.form['custom_field_textarea'] = 'foo bar'
resp.form['custom_field_bool'] = 'true'
resp.form.submit().follow()
event.refresh_from_db()
assert event.custom_fields == {
'text': 'foo',
'textarea': 'foo bar',
'bool': True,
}
resp = app.get('/manage/agendas/%s/events/%s/edit' % (agenda.pk, event.pk))
assert resp.form['custom_field_text'].value == 'foo'
assert resp.form['custom_field_textarea'].value == 'foo bar'
assert resp.form['custom_field_bool'].value == 'true'
resp.form['custom_field_text'] = ''
resp.form['custom_field_textarea'] = ''
resp.form['custom_field_bool'] = 'false'
resp.form.submit().follow()
event.refresh_from_db()
assert event.custom_fields == {
'text': '',
'textarea': '',
'bool': False,
}
resp = app.get('/manage/agendas/%s/events/%s/edit' % (agenda.pk, event.pk))
resp.form['custom_field_bool'] = 'unknown'
resp.form.submit().follow()
event.refresh_from_db()
assert event.custom_fields == {
'text': '',
'textarea': '',
'bool': None,
}
def test_edit_recurring_event(settings, app, admin_user, freezer):
freezer.move_to('2021-01-12 12:10')
events_type = EventsType.objects.create(
label='Foo', custom_fields=[{'varname': 'foo', 'label': 'Foo', 'field_type': 'text'}]
)
agenda = Agenda.objects.create(
label='Foo bar', kind='events', minimal_booking_delay=15, maximal_booking_delay=30
label='Foo bar',
kind='events',
minimal_booking_delay=15,
maximal_booking_delay=30,
events_type=events_type,
)
Desk.objects.create(agenda=agenda, slug='_exceptions_holder')
event = Event.objects.create(start_datetime=now(), places=10, agenda=agenda)
@ -314,9 +395,13 @@ def test_edit_recurring_event(settings, app, admin_user, freezer):
event_recurrence = Event.objects.get(primary_event=event, start_datetime=event.start_datetime)
resp = app.get('/manage/agendas/%s/events/%s/edit' % (agenda.id, event.id))
resp.form['places'] = 20
resp.form['custom_field_foo'] = 'bar'
resp = resp.form.submit().follow()
event_recurrence.refresh_from_db()
assert event_recurrence.places == 20
assert event_recurrence.custom_fields == {'foo': 'bar'}
event.refresh_from_db()
assert event.custom_fields == {'foo': 'bar'}
# but some fields should not be updated
assert event_recurrence.slug != event.slug
@ -371,7 +456,12 @@ def test_edit_recurring_event(settings, app, admin_user, freezer):
'recurrence_end_date',
'publication_datetime_0',
'publication_datetime_1',
'custom_field_foo',
}.isdisjoint(resp.form.fields)
resp.form.submit().follow()
# custom fields not changed
event_recurrence.refresh_from_db()
assert event_recurrence.custom_fields == {'foo': 'bar'}
def test_edit_recurring_event_with_end_date(settings, app, admin_user, freezer):