manager: reset user_was_present on booking check page (#75276)
gitea/chrono/pipeline/head There was a failure building this commit Details

This commit is contained in:
Lauréline Guérin 2023-03-14 11:56:51 +01:00
parent 6c134bfa3f
commit 970ba42075
No known key found for this signature in database
GPG Key ID: 1FAB9B9B4F93D473
6 changed files with 114 additions and 8 deletions

View File

@ -2195,6 +2195,18 @@ class Booking(models.Model):
self.secondary_booking_set.update(in_waiting_list=True)
self.save()
def reset_user_was_present(self):
self.user_check_type_slug = None
self.user_check_type_label = None
self.user_was_present = None
with transaction.atomic():
self.secondary_booking_set.update(user_check_type_slug=None)
self.secondary_booking_set.update(user_check_type_label=None)
self.secondary_booking_set.update(user_was_present=None)
self.save()
self.event.checked = False
self.event.save(update_fields=['checked'])
def mark_user_absence(self, check_type_slug=None, check_type_label=None):
self.user_check_type_slug = check_type_slug
self.user_check_type_label = check_type_label

View File

@ -47,6 +47,8 @@ $(function() {
$form.parent().parent().html(html);
if (!$('.booking-status.without-status').length) {
$('tr.booking.all-bookings').hide();
} else {
$('tr.booking.all-bookings').show();
}
}).fail(function() {
location.reload();

View File

@ -1,7 +1,7 @@
{% load i18n %}
<td class="booking-username main-list">{{ booking.get_user_block }}{% if booking.places_count > 1 %} ({{ booking.places_count }} {% trans "places" %}){% endif %}</td>
<td class="booking-status {% if booking.kind != "subscription" and booking.cancellation_datetime is None and booking.user_was_present is None %}without-status{% endif %}">
<td class="booking-status {% if booking.kind != "subscription" and booking.cancellation_datetime is None and booking.user_was_present is None %}without-status{% endif %}" data-{{ booking.kind }}-id="{{ booking.id }}">
{% if booking.kind == "subscription" %}
({% trans "Not booked" %})
{% elif booking.cancellation_datetime is None %}
@ -12,6 +12,23 @@
{% else %}
({% trans "Cancelled" %})
{% endif %}
{% if not event.checked or not agenda.disable_check_update %}
{% if booking.user_was_present is not None %}
<form method="post" action="{% url 'chrono-manager-booking-reset' pk=agenda.pk booking_pk=booking.pk %}" class="with-ajax reset">
{% csrf_token %}
<a href="#">{% trans "Reset" context "check" %}</a>
<script>
$(function() {
$('td.booking-status[data-{{ booking.kind }}-id="{{ booking.id }}"] form.reset a').on('click',
function(e) {
e.preventDefault();
$(this).parents('form.reset').submit();
});
});
</script>
</form>
{% endif %}
{% endif %}
</td>
{% if not event.checked or not agenda.disable_check_update %}
<td class="booking-actions" data-{{ booking.kind }}-id="{{ booking.id }}">
@ -27,7 +44,7 @@
{% if booking.presence_form.check_type.field.choices.1 %}{{ booking.presence_form.check_type }}{% endif %}
<script>
$(function() {
$('td[data-{{ booking.kind }}-id="{{ booking.id }}"] form.presence select').on('change',
$('td.booking-actions[data-{{ booking.kind }}-id="{{ booking.id }}"] form.presence select').on('change',
function() {
$(this).parents('form.presence').submit();
});
@ -46,7 +63,7 @@
{% if booking.absence_form.check_type.field.choices.1 %}{{ booking.absence_form.check_type }}{% endif %}
<script>
$(function() {
$('td[data-{{ booking.kind }}-id="{{ booking.id }}"] form.absence select').on('change',
$('td.booking-actions[data-{{ booking.kind }}-id="{{ booking.id }}"] form.absence select').on('change',
function() {
$(this).parents('form.absence').submit();
});

View File

@ -409,6 +409,11 @@ urlpatterns = [
views.booking_absence,
name='chrono-manager-booking-absence',
),
path(
'agendas/<int:pk>/bookings/<int:booking_pk>/reset',
views.booking_reset,
name='chrono-manager-booking-reset',
),
path(
'agendas/<int:pk>/subscriptions/<int:subscription_pk>/presence/<int:event_pk>',
views.subscription_presence,

View File

@ -3577,6 +3577,16 @@ class BookingAbsenceView(ViewableAgendaMixin, BookingCheckMixin, AbsenceViewMixi
booking_absence = BookingAbsenceView.as_view()
class BookingResetView(ViewableAgendaMixin, BookingCheckMixin, FormView):
def post(self, request, *args, **kwargs):
booking = self.get_booking(**kwargs)
booking.reset_user_was_present()
return self.response(request, booking)
booking_reset = BookingResetView.as_view()
class SubscriptionCheckMixin(BookingCheckMixin):
def get_booking(self, **kwargs):
event = get_object_or_404(

View File

@ -2167,12 +2167,32 @@ def test_event_check_booking(check_types, app, admin_user):
)
assert agenda.mark_event_checked_auto is False
def _test_reset():
resp = app.post(
'/manage/agendas/%s/bookings/%s/reset' % (agenda.pk, booking.pk),
params={'csrfmiddlewaretoken': token},
).follow()
assert '/manage/agendas/%s/bookings/%s/presence' % (agenda.pk, booking.pk) in resp
assert '/manage/agendas/%s/bookings/%s/absence' % (agenda.pk, booking.pk) in resp
assert '/manage/agendas/%s/bookings/%s/reset' % (agenda.pk, booking.pk) not in resp
booking.refresh_from_db()
assert booking.user_was_present is None
assert booking.user_check_type_slug is None
assert booking.user_check_type_label is None
secondary_booking.refresh_from_db()
assert secondary_booking.user_was_present is None
assert secondary_booking.user_check_type_slug is None
assert secondary_booking.user_check_type_label is None
event.refresh_from_db()
assert event.checked is False
login(app)
resp = app.get('/manage/agendas/%s/events/%s/check' % (agenda.pk, event.pk))
assert resp.pyquery.find('td.booking-status')[0].text.strip() == '-'
assert len(resp.pyquery.find('td.booking-actions button[disabled]')) == 0
assert '/manage/agendas/%s/bookings/%s/presence' % (agenda.pk, booking.pk) in resp
assert '/manage/agendas/%s/bookings/%s/absence' % (agenda.pk, booking.pk) in resp
assert '/manage/agendas/%s/bookings/%s/reset' % (agenda.pk, booking.pk) not in resp
# set as present
token = resp.context['csrf_token']
@ -2183,6 +2203,9 @@ def test_event_check_booking(check_types, app, admin_user):
assert resp.pyquery.find('td.booking-status')[0].text.strip() == 'Present'
assert len(resp.pyquery.find('td.booking-actions button[disabled]')) == 1
assert resp.pyquery.find('td.booking-actions button[disabled]')[0].text == 'Presence'
assert '/manage/agendas/%s/bookings/%s/presence' % (agenda.pk, booking.pk) in resp
assert '/manage/agendas/%s/bookings/%s/absence' % (agenda.pk, booking.pk) in resp
assert '/manage/agendas/%s/bookings/%s/reset' % (agenda.pk, booking.pk) in resp
booking.refresh_from_db()
assert booking.user_was_present is True
assert booking.user_check_type_slug is None
@ -2194,6 +2217,9 @@ def test_event_check_booking(check_types, app, admin_user):
event.refresh_from_db()
assert event.checked is False
# reset
_test_reset()
agenda.mark_event_checked_auto = True
agenda.save()
@ -2223,6 +2249,9 @@ def test_event_check_booking(check_types, app, admin_user):
assert len(resp.pyquery.find('td.booking-actions form.absence select')) == 1
assert len(resp.pyquery.find('td.booking-actions form.presence select')) == 0
# reset
_test_reset()
# set as absent with check_type
resp = app.post(
'/manage/agendas/%s/bookings/%s/absence' % (agenda.pk, booking.pk),
@ -2237,6 +2266,11 @@ def test_event_check_booking(check_types, app, admin_user):
assert secondary_booking.user_was_present is False
assert secondary_booking.user_check_type_slug == 'foo-reason'
assert secondary_booking.user_check_type_label == 'Foo reason'
event.refresh_from_db()
assert event.checked is True
# reset
_test_reset()
# set as present without check_type
resp = app.post(
@ -2269,6 +2303,9 @@ def test_event_check_booking(check_types, app, admin_user):
assert len(resp.pyquery.find('td.booking-actions form.absence select')) == 1
assert len(resp.pyquery.find('td.booking-actions form.presence select')) == 1
# reset
_test_reset()
# set as present with check_type
resp = app.post(
'/manage/agendas/%s/bookings/%s/presence' % (agenda.pk, booking.pk),
@ -2283,14 +2320,20 @@ def test_event_check_booking(check_types, app, admin_user):
assert secondary_booking.user_was_present is True
assert secondary_booking.user_check_type_slug == 'bar-reason'
assert secondary_booking.user_check_type_label == 'Bar reason'
event.refresh_from_db()
assert event.checked is True
# mark the event as checked
event.checked = True
event.save()
# event is checked
resp = app.get('/manage/agendas/%s/events/%s/check' % (agenda.pk, event.pk))
assert '/manage/agendas/%s/bookings/%s/presence' % (agenda.pk, booking.pk) in resp
assert '/manage/agendas/%s/bookings/%s/absence' % (agenda.pk, booking.pk) in resp
resp = app.post(
assert '/manage/agendas/%s/bookings/%s/reset' % (agenda.pk, booking.pk) in resp
app.post(
'/manage/agendas/%s/bookings/%s/reset' % (agenda.pk, booking.pk),
params={'csrfmiddlewaretoken': token},
status=302,
)
app.post(
'/manage/agendas/%s/bookings/%s/absence' % (agenda.pk, booking.pk),
params={'csrfmiddlewaretoken': token},
status=302,
@ -2307,7 +2350,8 @@ def test_event_check_booking(check_types, app, admin_user):
resp = app.get('/manage/agendas/%s/events/%s/check' % (agenda.pk, event.pk))
assert '/manage/agendas/%s/bookings/%s/presence' % (agenda.pk, booking.pk) not in resp
assert '/manage/agendas/%s/bookings/%s/absence' % (agenda.pk, booking.pk) not in resp
resp = app.post(
assert '/manage/agendas/%s/bookings/%s/reset' % (agenda.pk, booking.pk) not in resp
app.post(
'/manage/agendas/%s/bookings/%s/absence' % (agenda.pk, booking.pk),
params={'csrfmiddlewaretoken': token},
status=404,
@ -2317,6 +2361,11 @@ def test_event_check_booking(check_types, app, admin_user):
params={'csrfmiddlewaretoken': token},
status=404,
)
app.post(
'/manage/agendas/%s/bookings/%s/reset' % (agenda.pk, booking.pk),
params={'csrfmiddlewaretoken': token},
status=404,
)
@mock.patch('chrono.manager.forms.get_agenda_check_types')
@ -2343,6 +2392,7 @@ def test_event_check_cancelled_booking(check_types, app, admin_user):
assert len(resp.pyquery.find('td.booking-status')) == 1
assert '/manage/agendas/%s/bookings/%s/presence' % (agenda.pk, booking.pk) not in resp
assert '/manage/agendas/%s/bookings/%s/absence' % (agenda.pk, booking.pk) not in resp
assert '/manage/agendas/%s/bookings/%s/reset' % (agenda.pk, booking.pk) not in resp
token = resp.context['csrf_token']
resp = app.post(
'/manage/agendas/%s/bookings/%s/absence' % (agenda.pk, booking.pk),
@ -2370,6 +2420,7 @@ def test_event_check_cancelled_booking(check_types, app, admin_user):
assert len(resp.pyquery.find('td.booking-actions button[disabled]')) == 0
assert '/manage/agendas/%s/bookings/%s/presence' % (agenda.pk, booking.pk) in resp
assert '/manage/agendas/%s/bookings/%s/absence' % (agenda.pk, booking.pk) in resp
assert '/manage/agendas/%s/bookings/%s/reset' % (agenda.pk, booking.pk) not in resp
resp = app.post(
'/manage/agendas/%s/bookings/%s/presence' % (agenda.pk, booking.pk),
@ -2445,6 +2496,15 @@ def test_event_check_booking_ajax(check_types, app, admin_user):
assert resp.pyquery.find('td.booking-actions button[disabled]')[0].text.startswith('Absence')
assert '<option value="foo-reason" selected>Foo reason</option>' in resp
# reset
resp = app.post(
'/manage/agendas/%s/bookings/%s/reset' % (agenda.pk, booking.pk),
params={'csrfmiddlewaretoken': token},
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() == '-'
@mock.patch('chrono.manager.forms.get_agenda_check_types')
def test_event_check_subscription(check_types, app, admin_user):