manager: mark all bookings without status (#52813)

This commit is contained in:
Lauréline Guérin 2021-04-08 15:50:24 +02:00
parent c771a154f6
commit cf6a9c3ece
No known key found for this signature in database
GPG Key ID: 1FAB9B9B4F93D473
6 changed files with 173 additions and 4 deletions

View File

@ -30,7 +30,7 @@ $(function() {
});
}
$(document).on('submit', '.booking form', function(event) {
$(document).on('submit', '.booking form.with-ajax', function(event) {
var $form = $(this);
var formData = {
'csrfmiddlewaretoken': $('input[name=csrfmiddlewaretoken]', $form).val()
@ -45,6 +45,9 @@ $(function() {
data: formData
}).done(function(html) {
$form.parent().parent().html(html);
if (!$('.booking-status.without-status').length) {
$('tr.booking.all-bookings').hide();
}
}).fail(function() {
location.reload();
});

View File

@ -16,6 +16,30 @@
<div>
<table class="main check-bookings">
<tbody>
{% if booked_without_status %}
<tr class="booking all-bookings">
<td colspan="2"><b>{% trans "Mark all bookings without status:" %}</b></td>
<td class="booking-actions">
<form method="post" action="{% url 'chrono-manager-event-presence' pk=agenda.pk event_pk=object.pk %}">
{% csrf_token %}
<button class="submit-button">{% trans "Presence" %}</button>
</form>
<form method="post" action="{% url 'chrono-manager-event-absence' pk=agenda.pk event_pk=object.pk %}" id="all-bookings-absence">
{% csrf_token %}
<button class="submit-button">{% trans "Absence" %}</button>
{% if absence_form.reason.field.choices.1 %}{{ absence_form.reason }}{% endif %}
<script>
$(function() {
$('#all-bookings-absence select').on('change',
function() {
$('#all-bookings-absence').submit();
});
});
</script>
</form>
</td>
</tr>
{% endif %}
{% for booking in booked %}
<tr class="booking">
{% include "chrono/manager_event_check_booking_fragment.html" %}

View File

@ -1,20 +1,20 @@
{% load i18n %}
<td class="booking-username">{{ booking.user_name|default:booking.label|default:_('Unknown') }}</td>
<td class="booking-status">
<td class="booking-status {% if booking.user_was_present is None %}without-status{% endif %}">
{{ booking.user_was_present|yesno:_('Present,Absent,-') }}
{% if booking.user_was_present is False and booking.user_absence_reason %}
({{ booking.user_absence_reason }})
{% endif %}
</td>
<td class="booking-actions" data-booking-id="{{ booking.id }}">
<form method="post" action="{% url 'chrono-manager-booking-presence' pk=agenda.pk booking_pk=booking.pk %}">
<form method="post" action="{% url 'chrono-manager-booking-presence' pk=agenda.pk booking_pk=booking.pk %}" class="with-ajax">
{% csrf_token %}
<button class="submit-button"
{% if booking.user_was_present is True %}disabled{% endif %}
>{% trans "Presence" %}</button>
</form>
<form method="post" action="{% url 'chrono-manager-booking-absence' pk=agenda.pk booking_pk=booking.pk %}">
<form method="post" action="{% url 'chrono-manager-booking-absence' pk=agenda.pk booking_pk=booking.pk %}" class="with-ajax">
{% csrf_token %}
<button class="submit-button"
{% if booking.user_was_present is False %}disabled{% endif %}

View File

@ -211,6 +211,16 @@ urlpatterns = [
views.event_check,
name='chrono-manager-event-check',
),
url(
r'^agendas/(?P<pk>\d+)/events/(?P<event_pk>\d+)/presence$',
views.event_presence,
name='chrono-manager-event-presence',
),
url(
r'^agendas/(?P<pk>\d+)/events/(?P<event_pk>\d+)/absence$',
views.event_absence,
name='chrono-manager-event-absence',
),
url(
r'^agendas/(?P<pk>\d+)/event_cancellation_report/(?P<report_pk>\d+)/$',
views.event_cancellation_report,

View File

@ -1960,6 +1960,9 @@ class EventCheckView(ViewableAgendaMixin, DetailView):
context['booked'] = event.booking_set.filter(
cancellation_datetime__isnull=True, in_waiting_list=False
).order_by('user_name')
context['booked_without_status'] = any(e.user_was_present is None for e in context['booked'])
if context['booked_without_status']:
context['absence_form'] = BookingAbsenceReasonForm(agenda=self.agenda)
context['waiting'] = event.booking_set.filter(
cancellation_datetime__isnull=True, in_waiting_list=True
).order_by('user_name')
@ -1973,6 +1976,71 @@ class EventCheckView(ViewableAgendaMixin, DetailView):
event_check = EventCheckView.as_view()
class EventCheckMixin(object):
def set_agenda(self, **kwargs):
self.agenda = get_object_or_404(
Agenda,
pk=kwargs.get('pk'),
kind='events',
)
self.event = get_object_or_404(
Event,
pk=kwargs.get('event_pk'),
agenda=self.agenda,
start_datetime__date__lte=now().date(),
cancelled=False,
)
def get_bookings(self):
return self.event.booking_set.filter(
event__agenda=self.agenda,
event__start_datetime__date__lte=now().date(),
event__cancelled=False,
cancellation_datetime__isnull=True,
in_waiting_list=False,
user_was_present__isnull=True,
)
def response(self, request):
return HttpResponseRedirect(
reverse(
'chrono-manager-event-check',
kwargs={'pk': self.agenda.pk, 'event_pk': self.event.pk},
)
)
class EventPresenceView(EventCheckMixin, ViewableAgendaMixin, View):
def post(self, request, *args, **kwargs):
bookings = self.get_bookings()
bookings.update(user_absence_reason='', user_was_present=True)
return self.response(request)
event_presence = EventPresenceView.as_view()
class EventAbsenceView(EventCheckMixin, ViewableAgendaMixin, FormView):
form_class = BookingAbsenceReasonForm
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs['agenda'] = self.agenda
return kwargs
def post(self, request, *args, **kwargs):
form = self.get_form()
qs_kwargs = {}
if form.is_valid():
qs_kwargs['user_absence_reason'] = form.cleaned_data['reason']
bookings = self.get_bookings()
bookings.update(user_was_present=False, **qs_kwargs)
return self.response(request)
event_absence = EventAbsenceView.as_view()
class AgendaAddResourceView(ManagedAgendaMixin, FormView):
template_name = 'chrono/manager_agenda_resource_form.html'
form_class = AgendaResourceForm

View File

@ -1275,3 +1275,67 @@ def test_event_check_booking_ajax(app, admin_user):
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="Foo reason" selected>Foo reason</option>' in resp
def test_event_check_all_bookings(app, admin_user):
group = AbsenceReasonGroup.objects.create(label='Foo bar')
AbsenceReason.objects.create(label='Foo reason', group=group)
agenda = Agenda.objects.create(label='Events', kind='events', absence_reasons_group=group)
event = Event.objects.create(
label='xyz',
start_datetime=now() - datetime.timedelta(days=1),
places=10,
waiting_list_places=5,
agenda=agenda,
)
booking1 = Booking.objects.create(event=event, user_name='User 42')
login(app)
resp = app.get('/manage/agendas/%s/events/%s/check' % (agenda.pk, event.pk))
token = resp.context['csrf_token']
assert 'Mark all bookings without status' in resp
assert '/manage/agendas/%s/events/%s/presence' % (agenda.pk, event.pk) in resp
assert '/manage/agendas/%s/events/%s/absence' % (agenda.pk, event.pk) in resp
resp = app.post(
'/manage/agendas/%s/events/%s/absence' % (agenda.pk, event.pk), params={'csrfmiddlewaretoken': token}
)
booking1.refresh_from_db()
assert booking1.user_was_present is False
assert booking1.user_absence_reason == ''
resp = app.get('/manage/agendas/%s/events/%s/check' % (agenda.pk, event.pk))
assert 'Mark all bookings without status' not in resp
assert '/manage/agendas/%s/events/%s/presence' % (agenda.pk, event.pk) not in resp
assert '/manage/agendas/%s/events/%s/absence' % (agenda.pk, event.pk) not in resp
booking2 = Booking.objects.create(event=event, user_name='User 35')
resp = app.get('/manage/agendas/%s/events/%s/check' % (agenda.pk, event.pk))
assert 'Mark all bookings without status' in resp
assert '/manage/agendas/%s/events/%s/presence' % (agenda.pk, event.pk) in resp
assert '/manage/agendas/%s/events/%s/absence' % (agenda.pk, event.pk) in resp
app.post(
'/manage/agendas/%s/events/%s/presence' % (agenda.pk, event.pk), params={'csrfmiddlewaretoken': token}
)
booking1.refresh_from_db()
assert booking1.user_was_present is False
assert booking1.user_absence_reason == ''
booking2.refresh_from_db()
assert booking2.user_was_present is True
assert booking2.user_absence_reason == ''
booking3 = Booking.objects.create(event=event, user_name='User 51')
app.post(
'/manage/agendas/%s/events/%s/absence' % (agenda.pk, event.pk),
params={'csrfmiddlewaretoken': token, 'reason': 'Foo reason'},
)
booking1.refresh_from_db()
assert booking1.user_was_present is False
assert booking1.user_absence_reason == ''
booking2.refresh_from_db()
assert booking2.user_was_present is True
assert booking2.user_absence_reason == ''
booking3.refresh_from_db()
assert booking3.user_was_present is False
assert booking3.user_absence_reason == 'Foo reason'