manager: use check_types from lingo (#66015)

This commit is contained in:
Lauréline Guérin 2022-06-09 17:01:20 +02:00
parent 2d0cb4f1b2
commit 42e84a48a9
No known key found for this signature in database
GPG Key ID: 1FAB9B9B4F93D473
3 changed files with 96 additions and 114 deletions

View File

@ -67,6 +67,7 @@ from chrono.agendas.models import (
VirtualMember,
generate_slug,
)
from chrono.utils.lingo import get_agenda_check_types
from . import widgets
from .widgets import SplitDateTimeField, WeekdaysWidget
@ -444,19 +445,16 @@ class BookingCheckFilterSet(django_filters.FilterSet):
('not-checked', _('Not checked')),
('presence', _('Presence')),
]
if self.agenda.check_type_group:
status_choices += [
('presence::%s' % r.slug, _('Presence (%s)') % r.label)
for r in self.agenda.check_type_group.check_types.all()
if r.kind == 'presence' and not r.disabled
]
check_types = get_agenda_check_types(self.agenda)
absence_check_types = [ct for ct in check_types if ct.kind == 'absence']
presence_check_types = [ct for ct in check_types if ct.kind == 'presence']
status_choices += [
('presence::%s' % ct.slug, _('Presence (%s)') % ct.label) for ct in presence_check_types
]
status_choices += [('absence', _('Absence'))]
if self.agenda.check_type_group:
status_choices += [
('absence::%s' % r.slug, _('Absence (%s)') % r.label)
for r in self.agenda.check_type_group.check_types.all()
if r.kind == 'absence' and not r.disabled
]
status_choices += [
('absence::%s' % ct.slug, _('Absence (%s)') % ct.label) for ct in absence_check_types
]
self.filters['booking-status'] = django_filters.ChoiceFilter(
label=_('Filter by status'),
choices=status_choices,
@ -502,31 +500,29 @@ class SubscriptionCheckFilterSet(BookingCheckFilterSet):
class BookingCheckAbsenceForm(forms.Form):
check_type = forms.ChoiceField(required=False) # and not ModelChoiceField, to reduce querysets
check_type = forms.ChoiceField(required=False)
def __init__(self, *args, **kwargs):
agenda = kwargs.pop('agenda')
super().__init__(*args, **kwargs)
if agenda.check_type_group:
self.fields['check_type'].choices = [('', '---------')] + [
(r.slug, r.label)
for r in agenda.check_type_group.check_types.all()
if r.kind == 'absence' and not r.disabled
]
check_types = get_agenda_check_types(agenda)
self.absence_check_types = [ct for ct in check_types if ct.kind == 'absence']
self.fields['check_type'].choices = [('', '---------')] + [
(ct.slug, ct.label) for ct in self.absence_check_types
]
class BookingCheckPresenceForm(forms.Form):
check_type = forms.ChoiceField(required=False) # and not ModelChoiceField, to reduce querysets
check_type = forms.ChoiceField(required=False)
def __init__(self, *args, **kwargs):
agenda = kwargs.pop('agenda')
super().__init__(*args, **kwargs)
if agenda.check_type_group:
self.fields['check_type'].choices = [('', '---------')] + [
(r.slug, r.label)
for r in agenda.check_type_group.check_types.all()
if r.kind == 'presence' and not r.disabled
]
check_types = get_agenda_check_types(agenda)
self.presence_check_types = [ct for ct in check_types if ct.kind == 'presence']
self.fields['check_type'].choices = [('', '---------')] + [
(ct.slug, ct.label) for ct in self.presence_check_types
]
class EventsTimesheetForm(forms.Form):

View File

@ -2503,12 +2503,11 @@ class EventCheckMixin:
def get_check_type(self, kind):
form = self.get_form()
check_type = None
if form.is_valid() and form.cleaned_data['check_type']:
check_type = CheckType.objects.filter(
slug=form.cleaned_data['check_type'], kind=kind, group=self.agenda.check_type_group
).first()
return check_type
check_types = getattr(form, '%s_check_types' % kind)
for ct in check_types:
if ct.slug == form.cleaned_data['check_type']:
return ct
def response(self, request):
return HttpResponseRedirect(
@ -3266,12 +3265,11 @@ class BookingCheckMixin:
def get_check_type(self, kind):
form = self.get_form()
check_type = None
if form.is_valid() and form.cleaned_data['check_type']:
check_type = CheckType.objects.filter(
slug=form.cleaned_data['check_type'], kind=kind, group=self.agenda.check_type_group
).first()
return check_type
check_types = getattr(form, '%s_check_types' % kind)
for ct in check_types:
if ct.slug == form.cleaned_data['check_type']:
return ct
def response(self, request, booking):
if request.is_ajax():

View File

@ -10,16 +10,8 @@ from django.test.utils import CaptureQueriesContext
from django.utils.timezone import localtime, make_aware, now
from webtest import Upload
from chrono.agendas.models import (
Agenda,
Booking,
CheckType,
CheckTypeGroup,
Desk,
Event,
EventsType,
Subscription,
)
from chrono.agendas.models import Agenda, Booking, Desk, Event, EventsType, Subscription
from chrono.utils.lingo import CheckType
from tests.utils import login
pytestmark = pytest.mark.django_db
@ -1648,18 +1640,16 @@ def test_event_checked(app, admin_user):
assert '<span class="tag">Checked</span>' in resp
def test_event_check_filters(app, admin_user):
group = CheckTypeGroup.objects.create(label='Foo bar')
check_type_absence = CheckType.objects.create(label='Foo reason', group=group, kind='absence')
check_type_presence = CheckType.objects.create(label='Bar reason', group=group, kind='presence')
check_type_absence_disabled = CheckType.objects.create(
label='disabled', group=group, kind='absence', disabled=True
)
check_type_presence_disabled = CheckType.objects.create(
label='disabled too', group=group, kind='presence', disabled=True
)
@mock.patch('chrono.manager.forms.get_agenda_check_types')
def test_event_check_filters(check_types, app, admin_user):
check_types.return_value = [
CheckType(slug='foo-reason', label='Foo reason', kind='absence'),
CheckType(slug='bar-reason', label='Bar reason', kind='presence'),
]
agenda = Agenda.objects.create(
label='Events', kind='events', booking_check_filters='foo,bar', check_type_group=group
label='Events',
kind='events',
booking_check_filters='foo,bar',
)
event = Event.objects.create(
label='xyz',
@ -1707,7 +1697,7 @@ def test_event_check_filters(app, admin_user):
user_last_name='foo-none bar-val2 reason-foo',
extra_data={'bar': 'val2'},
user_was_present=False,
user_check_type_slug=check_type_absence.slug,
user_check_type_slug='foo-reason',
)
Booking.objects.create(
event=event,
@ -1716,7 +1706,7 @@ def test_event_check_filters(app, admin_user):
user_last_name='foo-none bar-val2 reason-bar',
extra_data={'bar': 'val2'},
user_was_present=True,
user_check_type_slug=check_type_presence.slug,
user_check_type_slug='bar-reason',
)
Booking.objects.create(
event=event,
@ -1725,7 +1715,7 @@ def test_event_check_filters(app, admin_user):
user_last_name='foo-none bar-val2 cancelled-absence',
extra_data={'bar': 'val2'},
user_was_present=False,
user_check_type_slug=check_type_absence.slug,
user_check_type_slug='foo-reason',
cancellation_datetime=now(),
)
Booking.objects.create(
@ -1735,7 +1725,7 @@ def test_event_check_filters(app, admin_user):
user_last_name='foo-none bar-val2 cancelled-presence',
extra_data={'bar': 'val2'},
user_was_present=True,
user_check_type_slug=check_type_presence.slug,
user_check_type_slug='bar-reason',
cancellation_datetime=now(),
)
@ -1816,14 +1806,12 @@ def test_event_check_filters(app, admin_user):
assert 'Subscription foo-val2 bar-val1' in resp
assert 'Subscription foo-val1 bar-val2' in resp
assert 'Subscription foo-none bar-val2' in resp
assert len(resp.pyquery.find('input[value=absence-%s]' % check_type_absence_disabled.slug)) == 0
assert len(resp.pyquery.find('input[value=absence-%s]' % check_type_presence_disabled.slug)) == 0
with CaptureQueriesContext(connection) as ctx:
resp = app.get(
'/manage/agendas/%s/events/%s/check' % (agenda.pk, event.pk), params={'extra-data-foo': 'val1'}
)
assert len(ctx.captured_queries) == 12
assert len(ctx.captured_queries) == 11
assert 'User none' not in resp
assert 'User empty' not in resp
assert 'User foo-val1 bar-none presence' in resp
@ -1996,7 +1984,7 @@ def test_event_check_filters(app, admin_user):
resp = app.get(
'/manage/agendas/%s/events/%s/check' % (agenda.pk, event.pk),
params={'booking-status': 'absence::%s' % check_type_absence.slug},
params={'booking-status': 'absence::foo-reason'},
)
assert 'User none' not in resp
assert 'User empty' not in resp
@ -2016,7 +2004,7 @@ def test_event_check_filters(app, admin_user):
resp = app.get(
'/manage/agendas/%s/events/%s/check' % (agenda.pk, event.pk),
params={'booking-status': 'presence::%s' % check_type_presence.slug},
params={'booking-status': 'presence::bar-reason'},
)
assert 'User none' not in resp
assert 'User empty' not in resp
@ -2073,8 +2061,9 @@ def test_event_check_ordering(app, admin_user):
assert resp.text.index('AA YY') < resp.text.index('BB XX') < resp.text.index('CC WW')
def test_event_check_booking(app, admin_user):
group = CheckTypeGroup.objects.create(label='Foo bar')
@mock.patch('chrono.manager.forms.get_agenda_check_types')
def test_event_check_booking(check_types, app, admin_user):
check_types.return_value = []
agenda = Agenda.objects.create(label='Events', kind='events')
event = Event.objects.create(
label='xyz',
@ -2138,15 +2127,9 @@ def test_event_check_booking(app, admin_user):
event.refresh_from_db()
assert event.checked is True
agenda.check_type_group = group
agenda.save()
CheckType.objects.create(label='disabled', group=group, kind='absence', disabled=True)
CheckType.objects.create(label='disabled too', group=group, kind='presence', disabled=True)
resp = app.get('/manage/agendas/%s/events/%s/check' % (agenda.pk, event.pk))
assert len(resp.pyquery.find('td.booking-actions form.absence select')) == 0
assert len(resp.pyquery.find('td.booking-actions form.presence select')) == 0
check_type_absence = CheckType.objects.create(label='Foo reason', group=group, kind='absence')
check_types.return_value = [
CheckType(slug='foo-reason', label='Foo reason', kind='absence'),
]
resp = app.get('/manage/agendas/%s/events/%s/check' % (agenda.pk, event.pk))
assert len(resp.pyquery.find('td.booking-actions form.absence select')) == 1
assert len(resp.pyquery.find('td.booking-actions form.presence select')) == 0
@ -2154,17 +2137,17 @@ def test_event_check_booking(app, admin_user):
# set as absent with check_type
resp = app.post(
'/manage/agendas/%s/bookings/%s/absence' % (agenda.pk, booking.pk),
params={'csrfmiddlewaretoken': token, 'check_type': check_type_absence.slug},
params={'csrfmiddlewaretoken': token, 'check_type': 'foo-reason'},
).follow()
assert 'Foo reason' in resp
booking.refresh_from_db()
assert booking.user_was_present is False
assert booking.user_check_type_slug == check_type_absence.slug
assert booking.user_check_type_label == check_type_absence.label
assert booking.user_check_type_slug == 'foo-reason'
assert booking.user_check_type_label == 'Foo reason'
secondary_booking.refresh_from_db()
assert secondary_booking.user_was_present is False
assert secondary_booking.user_check_type_slug == check_type_absence.slug
assert secondary_booking.user_check_type_label == check_type_absence.label
assert secondary_booking.user_check_type_slug == 'foo-reason'
assert secondary_booking.user_check_type_label == 'Foo reason'
# set as present without check_type
resp = app.post(
@ -2185,13 +2168,14 @@ def test_event_check_booking(app, admin_user):
event.refresh_from_db()
assert event.checked is True
agenda.check_type_group = group
agenda.save()
resp = app.get('/manage/agendas/%s/events/%s/check' % (agenda.pk, event.pk))
assert len(resp.pyquery.find('td.booking-actions form.absence select')) == 1
assert len(resp.pyquery.find('td.booking-actions form.presence select')) == 0
check_type_presence = CheckType.objects.create(label='Bar reason', group=group, kind='presence')
check_types.return_value = [
CheckType(slug='foo-reason', label='Foo reason', kind='absence'),
CheckType(slug='bar-reason', label='Bar reason', kind='presence'),
]
resp = app.get('/manage/agendas/%s/events/%s/check' % (agenda.pk, event.pk))
assert len(resp.pyquery.find('td.booking-actions form.absence select')) == 1
assert len(resp.pyquery.find('td.booking-actions form.presence select')) == 1
@ -2199,17 +2183,17 @@ def test_event_check_booking(app, admin_user):
# set as present with check_type
resp = app.post(
'/manage/agendas/%s/bookings/%s/presence' % (agenda.pk, booking.pk),
params={'csrfmiddlewaretoken': token, 'check_type': check_type_presence.slug},
params={'csrfmiddlewaretoken': token, 'check_type': 'bar-reason'},
).follow()
assert 'Bar reason' in resp
booking.refresh_from_db()
assert booking.user_was_present is True
assert booking.user_check_type_slug == check_type_presence.slug
assert booking.user_check_type_label == check_type_presence.label
assert booking.user_check_type_slug == 'bar-reason'
assert booking.user_check_type_label == 'Bar reason'
secondary_booking.refresh_from_db()
assert secondary_booking.user_was_present is True
assert secondary_booking.user_check_type_slug == check_type_presence.slug
assert secondary_booking.user_check_type_label == check_type_presence.label
assert secondary_booking.user_check_type_slug == 'bar-reason'
assert secondary_booking.user_check_type_label == 'Bar reason'
# mark the event as checked
event.checked = True
@ -2246,11 +2230,13 @@ def test_event_check_booking(app, admin_user):
)
def test_event_check_booking_ajax(app, admin_user):
group = CheckTypeGroup.objects.create(label='Foo bar')
check_type_absence = CheckType.objects.create(label='Foo reason', group=group)
check_type_presence = CheckType.objects.create(label='Bar reason', group=group, kind='presence')
agenda = Agenda.objects.create(label='Events', kind='events', check_type_group=group)
@mock.patch('chrono.manager.forms.get_agenda_check_types')
def test_event_check_booking_ajax(check_types, app, admin_user):
check_types.return_value = [
CheckType(slug='foo-reason', label='Foo reason', kind='absence'),
CheckType(slug='bar-reason', label='Bar reason', kind='presence'),
]
agenda = Agenda.objects.create(label='Events', kind='events')
event = Event.objects.create(
label='xyz',
start_datetime=now() - datetime.timedelta(days=1),
@ -2267,33 +2253,35 @@ def test_event_check_booking_ajax(app, admin_user):
# set as present
resp = app.post(
'/manage/agendas/%s/bookings/%s/presence' % (agenda.pk, booking.pk),
params={'csrfmiddlewaretoken': token, 'check_type': check_type_presence.slug},
params={'csrfmiddlewaretoken': token, 'check_type': 'bar-reason'},
extra_environ={'HTTP_X_REQUESTED_WITH': 'XMLHttpRequest'},
)
assert '<tr>' not in resp # because this is a fragment
assert resp.pyquery.find('td.booking-status')[0].text.strip() == 'Present\n \n (Bar reason)'
assert len(resp.pyquery.find('td.booking-actions button[disabled]')) == 1
assert resp.pyquery.find('td.booking-actions button[disabled]')[0].text == 'Presence'
assert '<option value="%s" selected>Bar reason</option>' % check_type_presence.slug in resp
assert '<option value="bar-reason" selected>Bar reason</option>' in resp
# set as absent
resp = app.post(
'/manage/agendas/%s/bookings/%s/absence' % (agenda.pk, booking.pk),
params={'csrfmiddlewaretoken': token, 'check_type': check_type_absence.slug},
params={'csrfmiddlewaretoken': token, 'check_type': 'foo-reason'},
extra_environ={'HTTP_X_REQUESTED_WITH': 'XMLHttpRequest'},
)
assert '<tr>' not in resp # because this is a fragment
assert resp.pyquery.find('td.booking-status')[0].text.strip() == 'Absent\n \n (Foo reason)'
assert len(resp.pyquery.find('td.booking-actions button[disabled]')) == 1
assert resp.pyquery.find('td.booking-actions button[disabled]')[0].text.startswith('Absence')
assert '<option value="%s" selected>Foo reason</option>' % check_type_absence.slug in resp
assert '<option value="foo-reason" selected>Foo reason</option>' in resp
def test_event_check_all_bookings(app, admin_user):
group = CheckTypeGroup.objects.create(label='Foo bar')
check_type_absence = CheckType.objects.create(label='Foo reason', group=group)
check_type_presence = CheckType.objects.create(label='Bar reason', group=group, kind='presence')
agenda = Agenda.objects.create(label='Events', kind='events', check_type_group=group)
@mock.patch('chrono.manager.forms.get_agenda_check_types')
def test_event_check_all_bookings(check_types, app, admin_user):
check_types.return_value = [
CheckType(slug='foo-reason', label='Foo reason', kind='absence'),
CheckType(slug='bar-reason', label='Bar reason', kind='presence'),
]
agenda = Agenda.objects.create(label='Events', kind='events')
event = Event.objects.create(
label='xyz',
start_datetime=now() - datetime.timedelta(days=1),
@ -2362,7 +2350,7 @@ def test_event_check_all_bookings(app, admin_user):
assert 'Mark all bookings without status' in resp
app.post(
'/manage/agendas/%s/events/%s/absence' % (agenda.pk, event.pk),
params={'csrfmiddlewaretoken': token, 'check_type': check_type_absence.slug},
params={'csrfmiddlewaretoken': token, 'check_type': 'foo-reason'},
)
booking1.refresh_from_db()
assert booking1.user_was_present is False
@ -2374,15 +2362,15 @@ def test_event_check_all_bookings(app, admin_user):
assert booking2.user_check_type_label is None
booking3.refresh_from_db()
assert booking3.user_was_present is False
assert booking3.user_check_type_slug == check_type_absence.slug
assert booking3.user_check_type_label == check_type_absence.label
assert booking3.user_check_type_slug == 'foo-reason'
assert booking3.user_check_type_label == 'Foo reason'
booking4 = Booking.objects.create(event=event, user_first_name='User', user_last_name='52')
resp = app.get('/manage/agendas/%s/events/%s/check' % (agenda.pk, event.pk))
assert 'Mark all bookings without status' in resp
app.post(
'/manage/agendas/%s/events/%s/presence' % (agenda.pk, event.pk),
params={'csrfmiddlewaretoken': token, 'check_type': check_type_presence.slug},
params={'csrfmiddlewaretoken': token, 'check_type': 'bar-reason'},
)
booking1.refresh_from_db()
assert booking1.user_was_present is False
@ -2394,12 +2382,12 @@ def test_event_check_all_bookings(app, admin_user):
assert booking2.user_check_type_label is None
booking3.refresh_from_db()
assert booking3.user_was_present is False
assert booking3.user_check_type_slug == check_type_absence.slug
assert booking3.user_check_type_label == check_type_absence.label
assert booking3.user_check_type_slug == 'foo-reason'
assert booking3.user_check_type_label == 'Foo reason'
booking4.refresh_from_db()
assert booking4.user_was_present is True
assert booking4.user_check_type_slug == check_type_presence.slug
assert booking4.user_check_type_label == check_type_presence.label
assert booking4.user_check_type_slug == 'bar-reason'
assert booking4.user_check_type_label == 'Bar reason'
# now disable check update
agenda.disable_check_update = True
@ -2409,7 +2397,7 @@ def test_event_check_all_bookings(app, admin_user):
assert 'Mark all bookings without status' not in resp
app.post(
'/manage/agendas/%s/events/%s/absence' % (agenda.pk, event.pk),
params={'csrfmiddlewaretoken': token, 'check_type': check_type_absence.slug},
params={'csrfmiddlewaretoken': token, 'check_type': 'foo-reason'},
status=404,
)
resp = app.post(
@ -2419,7 +2407,7 @@ def test_event_check_all_bookings(app, admin_user):
)
app.post(
'/manage/agendas/%s/events/%s/presence' % (agenda.pk, event.pk),
params={'csrfmiddlewaretoken': token, 'check_type': check_type_presence.slug},
params={'csrfmiddlewaretoken': token, 'check_type': 'bar-reason'},
status=404,
)
resp = app.post(