manager: regroup partial booking check operations in one form (#82231)
gitea/chrono/pipeline/head There was a failure building this commit Details

This commit is contained in:
Valentin Deniaud 2023-11-13 14:42:16 +01:00
parent 1ab0897039
commit 21ff47b82d
7 changed files with 276 additions and 160 deletions

View File

@ -612,6 +612,7 @@ class PartialBookingCheckForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
agenda = kwargs.pop('agenda')
hide_buttons = kwargs.pop('hide_buttons')
super().__init__(*args, **kwargs)
self.check_types = get_agenda_check_types(agenda)
absence_check_types = [(ct.slug, ct.label) for ct in self.check_types if ct.kind == 'absence']
@ -629,9 +630,11 @@ class PartialBookingCheckForm(forms.ModelForm):
else:
del self.fields['absence_check_type']
if not self.instance.booking.start_time:
if hide_buttons:
self.fields['start_time'].widget = widgets.TimeWidget(step=60)
self.fields['end_time'].widget = widgets.TimeWidget(step=60)
if not self.instance.booking.start_time:
self.fields['presence'].widget.choices = ((None, _('Not checked')), (True, _('Present')))
self.fields.pop('absence_check_type', None)

View File

@ -729,6 +729,15 @@ div#main-content.partial-booking-dayview {
}
}
.partial-booking--check-icon {
border: 0;
&::before {
content: "\f017"; /* clock */
font-family: FontAwesome;
padding-left: 1ex;
}
}
/* ants-hub */
ul.objects-list.single-links li.ants-setting-not-configured a.edit {
color: red;

View File

@ -7,28 +7,68 @@
{% endblock %}
{% block appbar %}
<h2>{% trans "Check booking" %}</h2>
<h2>
{% blocktrans trimmed with user=view.bookings.0.user_name %}
Check booking for {{ user }}
{% endblocktrans %}
</h2>
{% endblock %}
{% block content %}
{% if multiple_bookings %}
<div class="pk-tabs">
<div class="pk-tabs--tab-list" role="tablist" aria-label="{% trans "Booking tabs" %}">
{% for booking in view.bookings %}
<button role="tab"
aria-selected="{{ forloop.first|yesno:"true,false" }}"
aria-controls="panel-{{ booking.pk }}"
id="tab-{{ booking.pk }}"
tabindex="{{ forloop.first|yesno:"0,-1" }}"
>
{{ booking.start_time }} - {{ booking.end_time }}
</button>
{% endfor %}
</div>
{% endif %}
<form
method="post"
enctype="multipart/form-data"
data-fill-start_time="{{ object.booking.start_time|time:"H:i" }}"
data-fill-end_time="{{ object.booking.end_time|time:"H:i" }}"
{% if multiple_bookings %}class="pk-tabs--container"{% endif %}
>
{% if allow_adding_check %}
<p>
<a
rel="popup"
href="{% url 'chrono-manager-partial-booking-check' pk=agenda.pk booking_pk=object.booking.pk %}"
>
{% trans "Add second booking check" %}
</a>
</p>
{% endif %}
{% csrf_token %}
{{ form|with_template }}
{% for booking in view.bookings %}
{% if multiple_bookings %}
<div id="panel-{{ booking.pk }}"
role="tabpanel" tabindex="0" {% if not forloop.first %}hidden{% endif %}
data-tab-slug="{{ booking.pk }}"
aria-labelledby="tab-{{ booking.pk }}">
{% endif %}
<div
class="booking-check-form"
data-fill-start_time="{{ booking.start_time|time:"H:i" }}"
data-fill-end_time="{{ booking.end_time|time:"H:i" }}"
>
{{ booking.check_forms.0|with_template }}
</div>
{% if forms|length > 1 %}
<fieldset
class="gadjo-foldable {% if not forms.1.instance.pk and not forms.1.errors %}gadjo-folded{% endif %}"
>
<legend class="gadjo-foldable-widget">{% trans "Second booking check" %}</legend>
<div class="booking-check-form gadjo-folding">
{{ booking.check_forms.1|with_template }}
</div>
</fieldset>
{% endif %}
{% if multiple_bookings %}</div>{% endif %}
{% endfor %}
<div class="buttons">
<button class="submit-button">{% trans "Save" %}</button>
<a class="cancel" href="{{ agenda.get_absolute_url }}">{% trans 'Cancel' %}</a>
@ -36,28 +76,37 @@
<script>
$(function () {
presence_check_type_select = $('.widget[id=id_presence_check_type_p]');
absence_check_type_select = $('.widget[id=id_absence_check_type_p]');
$('input[type=radio][name=presence]').change(function() {
if (!this.checked)
return;
if (this.value == 'True') {
$(this).parents('.widget').siblings('.widget').show();
absence_check_type_select.hide();
} else if (this.value == 'False') {
$(this).parents('.widget').siblings('.widget').show();
presence_check_type_select.hide();
} else {
$(this).parents('.widget').siblings('.widget').hide();
}
}).change();
// Tabs are not loaded if form is in popup, remove this block when fixed in gadjo
$(document.querySelectorAll('.pk-tabs')).each(function(i, el) {
el.tabs = new gadjo_js.Tabs(el);
});
$('.booking-check-form').each(function () {
let presence_check_type_select = $(this).children('.widget[id*=presence_check_type]');
let absence_check_type_select = $(this).children('.widget[id*=absence_check_type]');
$(this).find('input[type=radio][name*=presence]').change(function() {
if (!this.checked)
return;
if (this.value == 'True') {
$(this).parents('.widget').siblings('.widget').show();
absence_check_type_select.hide();
} else if (this.value == 'False') {
$(this).parents('.widget').siblings('.widget').show();
presence_check_type_select.hide();
} else {
$(this).parents('.widget').siblings('.widget').hide();
}
}).change();
});
$('.time-widget-button').on('click', function() {
var widget_name = $(this).data('related-widget');
var value = $(this).parents('form').data('fill-' + widget_name);
var widget_id = widget_name.split('-').at(-1);
var value = $(this).parents('.booking-check-form').data('fill-' + widget_id);
$('[name="' + widget_name + '"]').val(value);
});
});
</script>
</form>
{% if multiple_bookings %}</div>{% endif %}
{% endblock %}

View File

@ -56,13 +56,14 @@
<section class="partial-booking--registrant">
{% spaceless %}
<h3 class="registrant--name">
{% if allow_check and user.check_url %}
<span class="registrant--name-label">{{ user.name }}</span>
{% if allow_check %}
<a
class="partial-booking--check-icon"
rel="popup"
{% if user.bookings|length > 1 %}data-selector=".pk-tabs"{% endif %}
href="{{ user.check_url }}"
>{{ user.name }}</a>
{% else %}
<span>{{ user.name }}</span>
><span class="sr-only">{% trans "Check" %}</span></a>
{% endif %}
</h3>
{% endspaceless %}
@ -70,33 +71,25 @@
<div class="registrant--bar-container">
{% for booking in user.bookings %}
{% if booking.start_time %}
<a
<p
class="registrant--bar clearfix booking"
title="{% trans "Booked period" %}"
style="left: {{ booking.css_left }}%; width: {{ booking.css_width }}%;"
{% if allow_check and not booking.user_check %}
rel="popup"
href="{% url 'chrono-manager-partial-booking-check' pk=agenda.pk booking_pk=booking.pk %}"
{% endif %}
>
<strong class="sr-only">{% trans "Booked period:" %}</strong>
<time class="start-time" datetime="{{ booking.start_time|time:"H:i" }}">{{ booking.start_time|time:"H:i" }}</time>
<time class="end-time" datetime="{{ booking.end_time|time:"H:i" }}">{{ booking.end_time|time:"H:i" }}</time>
</a>
</p>
{% endif %}
{% endfor %}
</div>
{% if user.bookings %}
<div class="registrant--bar-container">
{% for check in user.booking_checks %}
<a
<p
class="registrant--bar clearfix check {{ check.css_class }}"
title="{% trans "Checked period" %}"
style="left: {{ check.css_left }}%; width: {{ check.css_width }}%;"
{% if allow_check %}
rel="popup"
href="{% url 'chrono-manager-partial-booking-update-check' pk=agenda.pk check_pk=check.pk %}"
{% endif %}
>
<strong class="sr-only">{% trans "Checked period:" %}</strong>
{% if check.start_time %}
@ -106,7 +99,7 @@
<time class="end-time" datetime="{{ check.end_time|time:"H:i" }}">{{ check.end_time|time:"H:i" }}</time>
{% endif %}
{% if check.type_label %}<span>{{ check.type_label }}</span>{% endif %}
</a>
</p>
{% endfor %}
</div>
<div class="registrant--bar-container">

View File

@ -435,20 +435,10 @@ urlpatterns = [
name='chrono-manager-booking-extra-user-block',
),
path(
'agendas/<int:pk>/bookings/<int:booking_pk>/check',
'agendas/<int:pk>/events/<int:event_pk>/check-bookings/<str:user_external_id>',
views.partial_booking_check_view,
name='chrono-manager-partial-booking-check',
),
path(
'agendas/<int:pk>/booking-checks/<int:check_pk>',
views.partial_booking_update_check_view,
name='chrono-manager-partial-booking-update-check',
),
path(
'agendas/<int:pk>/subscriptions/<int:subscription_pk>/check/<int:event_pk>',
views.partial_booking_subscription_check_view,
name='chrono-manager-partial-booking-subscription-check',
),
path(
'agendas/<int:pk>/subscriptions/<int:subscription_pk>/extra-user-block',
views.subscription_extra_user_block,

View File

@ -30,7 +30,7 @@ from django.conf import settings
from django.contrib import messages
from django.core.exceptions import PermissionDenied
from django.db import IntegrityError, transaction
from django.db.models import BooleanField, Count, Max, Min, Q, Value
from django.db.models import BooleanField, Count, Max, Min, Prefetch, Q, Value
from django.db.models.deletion import ProtectedError
from django.http import Http404, HttpResponse, HttpResponseForbidden, HttpResponseRedirect
from django.shortcuts import get_object_or_404, redirect, render
@ -1690,13 +1690,17 @@ class AgendaDayView(EventChecksMixin, AgendaDateView, DayArchiveView):
'name': result.user_name,
'bookings': [],
'booking_checks': [],
'check_url': reverse(
'chrono-manager-partial-booking-check',
kwargs={
'pk': self.agenda.pk,
'event_pk': event.pk,
'user_external_id': result.user_external_id,
},
),
},
)
if result.kind == 'subscription':
user_info['check_url'] = reverse(
'chrono-manager-partial-booking-subscription-check',
kwargs={'pk': self.agenda.pk, 'event_pk': event.pk, 'subscription_pk': result.pk},
)
continue
user_info['bookings'].append(result)
user_info['booking_checks'].extend(result.user_check_list)
@ -4531,61 +4535,128 @@ class SharedCustodySettingsView(UpdateView):
shared_custody_settings = SharedCustodySettingsView.as_view()
class PartialBookingCheckMixin(ViewableAgendaMixin):
class PartialBookingCheckView(ViewableAgendaMixin, TemplateView):
template_name = 'chrono/manager_partial_booking_form.html'
form_class = PartialBookingCheckForm
def get_object(self):
booking = self.get_booking(**self.kwargs)
return BookingCheck(booking=booking)
def dispatch(self, *args, **kwargs):
self.set_agenda(**kwargs)
self.event = get_object_or_404(
Event,
Q(checked=False) | Q(agenda__disable_check_update=False),
pk=kwargs['event_pk'],
agenda=self.agenda,
check_locked=False,
)
self.bookings = Booking.objects.filter(
event=self.event, user_external_id=kwargs['user_external_id']
).order_by('start_time')
if not self.bookings:
subscription = get_object_or_404(
Subscription,
agenda=self.agenda,
user_external_id=kwargs['user_external_id'],
date_start__lte=self.event.start_datetime,
date_end__gt=self.event.start_datetime,
)
# create dummy booking to allow check
booking = self.event.booking_set.create(
user_external_id=subscription.user_external_id,
user_last_name=subscription.user_last_name,
user_first_name=subscription.user_first_name,
user_email=subscription.user_email,
user_phone_number=subscription.user_phone_number,
extra_data=subscription.extra_data,
)
self.bookings = [booking]
self.multiple_bookings = bool(len(self.bookings) > 1)
return super().dispatch(*args, **kwargs)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['forms'] = self.get_forms()
context['multiple_bookings'] = self.multiple_bookings
return context
def get_forms(self):
kwargs = {
'agenda': self.agenda,
}
if self.request.method == 'POST':
kwargs['data'] = self.request.POST
forms = []
for i, booking in enumerate(self.bookings):
is_dummy_booking = bool(not booking.start_time)
checks = booking.user_checks.all()
first_check = checks[0] if len(checks) > 0 else BookingCheck(booking=booking)
second_check = checks[1] if len(checks) > 1 else BookingCheck(booking=booking)
first_check_initial = {}
if i == 0 and first_check.presence is None:
first_check_initial['presence'] = True
booking.check_forms = [
PartialBookingCheckForm(
instance=first_check,
prefix=self.get_prefix(booking),
initial=first_check_initial,
hide_buttons=is_dummy_booking,
**kwargs,
),
]
if not is_dummy_booking:
booking.check_forms.append(
PartialBookingCheckForm(
instance=second_check,
prefix=self.get_prefix(booking, second_check=True),
hide_buttons=True,
**kwargs,
)
)
forms.extend(booking.check_forms)
return forms
def get_prefix(self, booking, second_check=False):
parts = []
if self.multiple_bookings:
parts.append('booking-%s' % booking.pk)
if second_check:
parts.append('check-2')
return '-'.join(parts)
def post(self, *args, **kwargs):
forms = self.get_forms()
all_valid = all(form.is_valid() for form in forms)
if all_valid:
for form in forms:
form.save()
return HttpResponseRedirect(self.get_success_url())
return self.render_to_response(self.get_context_data(forms=forms))
def get_success_url(self):
date = self.object.booking.event.start_datetime
date = self.event.start_datetime
return reverse(
'chrono-manager-agenda-day-view',
kwargs={'pk': self.agenda.pk, 'year': date.year, 'month': date.month, 'day': date.day},
)
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs['agenda'] = self.agenda
return kwargs
class PartialBookingCheckView(PartialBookingCheckMixin, BookingCheckMixin, UpdateView):
pass
partial_booking_check_view = PartialBookingCheckView.as_view()
class PartialBookingSubscriptionCheckView(PartialBookingCheckMixin, SubscriptionCheckMixin, UpdateView):
def get_object(self):
if self.request.method == 'POST':
return super().get_object()
else:
return BookingCheck(booking=Booking())
partial_booking_subscription_check_view = PartialBookingSubscriptionCheckView.as_view()
class PartialBookingUpdateCheckView(PartialBookingCheckMixin, UpdateView):
model = BookingCheck
pk_url_kwarg = 'check_pk'
def get_object(self):
return super(PartialBookingCheckMixin, self).get_object()
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['allow_adding_check'] = bool(self.object.booking.user_checks.count() == 1)
return context
partial_booking_update_check_view = PartialBookingUpdateCheckView.as_view()
def menu_json(request):
if not request.user.is_staff:
homepage_view = HomepageView(request=request)

View File

@ -194,9 +194,9 @@ def test_manager_partial_bookings_day_view(app, admin_user, freezer):
)
assert len(resp.pyquery('.partial-booking--registrant')) == 3
assert resp.pyquery('.registrant--name')[0].text_content() == 'Bruce Doe'
assert resp.pyquery('.registrant--name')[1].text_content() == 'Jane Doe'
assert resp.pyquery('.registrant--name')[2].text_content() == 'Jon Doe'
assert resp.pyquery('.registrant--name-label')[0].text_content() == 'Bruce Doe'
assert resp.pyquery('.registrant--name-label')[1].text_content() == 'Jane Doe'
assert resp.pyquery('.registrant--name-label')[2].text_content() == 'Jon Doe'
assert resp.pyquery('.registrant--bar')[0].findall('time')[0].text == '12:00'
assert resp.pyquery('.registrant--bar')[0].findall('time')[1].text == '14:00'
@ -250,7 +250,7 @@ def test_manager_partial_bookings_day_view_multiple_bookings(app, admin_user, fr
event = Event.objects.create(
label='Event', start_datetime=start_datetime, end_time=datetime.time(18, 00), places=10, agenda=agenda
)
Booking.objects.create(
first_booking = Booking.objects.create(
user_external_id='xxx',
user_first_name='Jane',
user_last_name='Doe',
@ -258,7 +258,7 @@ def test_manager_partial_bookings_day_view_multiple_bookings(app, admin_user, fr
end_time=datetime.time(12, 00),
event=event,
)
Booking.objects.create(
second_booking = Booking.objects.create(
user_external_id='xxx',
user_first_name='Jane',
user_last_name='Doe',
@ -279,10 +279,11 @@ def test_manager_partial_bookings_day_view_multiple_bookings(app, admin_user, fr
assert resp.pyquery('.registrant--bar')[1].findall('time')[1].text == '18:00'
# check first booking
resp = resp.click('Booked period', index=0)
resp.form['start_time'] = '09:30'
resp.form['end_time'] = '12:00'
resp.form['presence'] = 'True'
resp = resp.click('Check')
prefix = 'booking-%s-' % first_booking.pk
resp.form[prefix + 'start_time'] = '09:30'
resp.form[prefix + 'end_time'] = '12:00'
resp.form[prefix + 'presence'] = 'True'
resp = resp.form.submit().follow()
assert len(resp.pyquery('.partial-booking--registrant')) == 1
@ -293,10 +294,11 @@ def test_manager_partial_bookings_day_view_multiple_bookings(app, admin_user, fr
assert resp.pyquery('.registrant--bar.check')[0].findall('time')[1].text == '12:00'
# check second booking
resp = resp.click('Booked period')
resp.form['start_time'] = '15:00'
resp.form['end_time'] = '17:00'
resp.form['presence'] = 'True'
resp = resp.click('Check')
prefix = 'booking-%s-' % second_booking.pk
resp.form[prefix + 'start_time'] = '15:00'
resp.form[prefix + 'end_time'] = '17:00'
resp.form[prefix + 'presence'] = 'True'
resp = resp.form.submit().follow()
assert len(resp.pyquery('.partial-booking--registrant')) == 1
@ -335,20 +337,20 @@ def test_manager_partial_bookings_check(check_types, app, admin_user):
assert resp.pyquery('.registrant--bar time')[1].text == '13:30'
assert resp.pyquery('.registrant--bar')[0].attrib['style'] == 'left: 30.77%; width: 19.23%;'
resp = resp.click('Booked period')
resp = resp.click('Check')
assert 'presence_check_type' not in resp.form.fields
assert 'absence_check_type' not in resp.form.fields
assert resp.pyquery('form').attr('data-fill-start_time') == '11:00'
assert resp.pyquery('form').attr('data-fill-end_time') == '13:30'
assert resp.pyquery('.booking-check-form').attr('data-fill-start_time') == '11:00'
assert resp.pyquery('.booking-check-form').attr('data-fill-end_time') == '13:30'
assert resp.pyquery('.time-widget-button')[0].text == 'Fill with booking start time'
assert resp.pyquery('.time-widget-button')[1].text == 'Fill with booking end time'
# submitting empty form works
assert resp.form['presence'].value == ''
resp.form['presence'] = ''
resp = resp.form.submit().follow()
resp = resp.click('Booked period')
resp = resp.click('Check')
resp.form['start_time'] = '11:01'
resp.form['end_time'] = '11:00'
resp.form['presence'] = 'True'
@ -393,7 +395,7 @@ def test_manager_partial_bookings_check(check_types, app, admin_user):
CheckType(slug='bar-reason', label='Bar reason', kind='presence'),
CheckType(slug='baz-reason', label='Baz reason', kind='presence'),
]
resp = resp.click('Checked period')
resp = resp.click('Check')
assert resp.form['presence_check_type'].options == [
('', True, '---------'),
('bar-reason', False, 'Bar reason'),
@ -418,7 +420,7 @@ def test_manager_partial_bookings_check(check_types, app, admin_user):
assert resp.pyquery('.registrant--bar.computed time')[1].text == '13:30'
assert resp.pyquery('.registrant--bar.computed')[0].attrib['style'] == 'left: 30.77%; width: 19.23%;'
resp = resp.click('Checked period')
resp = resp.click('Check')
assert resp.form['presence_check_type'].value == 'bar-reason'
resp.form['presence'] = 'False'
@ -430,7 +432,7 @@ def test_manager_partial_bookings_check(check_types, app, admin_user):
assert len(resp.pyquery('.registrant--bar.computed.absent')) == 1
assert resp.pyquery('.registrant--bar span').text() == ''
resp = resp.click('Checked period')
resp = resp.click('Check')
resp.form['presence'] = ''
resp = resp.form.submit().follow()
assert len(resp.pyquery('.registrant--bar')) == 1
@ -442,15 +444,15 @@ def test_manager_partial_bookings_check(check_types, app, admin_user):
event.save()
assert agenda.disable_check_update is False
resp = app.get('/manage/agendas/%s/day/%d/%d/%d/' % (agenda.pk, today.year, today.month, today.day))
assert '/manage/agendas/%s/bookings/%s/check' % (agenda.pk, booking.pk) in resp
app.get('/manage/agendas/%s/bookings/%s/check' % (agenda.pk, booking.pk), status=200)
assert '/manage/agendas/%s/events/%s/check-bookings/xxx' % (agenda.pk, event.pk) in resp
app.get('/manage/agendas/%s/events/%s/check-bookings/xxx' % (agenda.pk, event.pk), status=200)
# event check is locked
event.check_locked = True
event.save()
resp = app.get('/manage/agendas/%s/day/%d/%d/%d/' % (agenda.pk, today.year, today.month, today.day))
assert '/manage/agendas/%s/bookings/%s/check' % (agenda.pk, booking.pk) not in resp
app.get('/manage/agendas/%s/bookings/%s/check' % (agenda.pk, booking.pk), status=404)
assert '/manage/agendas/%s/events/%s/check-bookings/xxx' % (agenda.pk, event.pk) not in resp
app.get('/manage/agendas/%s/events/%s/check-bookings/xxx' % (agenda.pk, event.pk), status=404)
# now disable check update
event.check_locked = False
@ -458,8 +460,8 @@ def test_manager_partial_bookings_check(check_types, app, admin_user):
agenda.disable_check_update = True
agenda.save()
resp = app.get('/manage/agendas/%s/day/%d/%d/%d/' % (agenda.pk, today.year, today.month, today.day))
assert '/manage/agendas/%s/bookings/%s/check' % (agenda.pk, booking.pk) not in resp
app.get('/manage/agendas/%s/bookings/%s/check' % (agenda.pk, booking.pk), status=404)
assert '/manage/agendas/%s/events/%s/check-bookings/xxx' % (agenda.pk, event.pk) not in resp
app.get('/manage/agendas/%s/events/%s/check-bookings/xxx' % (agenda.pk, event.pk), status=404)
def test_manager_partial_bookings_multiple_checks(app, admin_user):
@ -481,9 +483,7 @@ def test_manager_partial_bookings_multiple_checks(app, admin_user):
today = start_datetime.date()
resp = app.get('/manage/agendas/%s/day/%d/%d/%d/' % (agenda.pk, today.year, today.month, today.day))
resp = resp.click('Booked period')
assert 'Add second booking check' not in resp.text
resp = resp.click('Check')
resp.form['start_time'] = '09:30'
resp.form['end_time'] = '12:00'
resp.form['presence'] = 'True'
@ -495,12 +495,11 @@ def test_manager_partial_bookings_multiple_checks(app, admin_user):
assert resp.pyquery('.registrant--bar.check')[0].findall('time')[0].text == '09:30'
assert resp.pyquery('.registrant--bar.check')[0].findall('time')[1].text == '12:00'
resp = resp.click('Checked period')
resp = resp.click('Add second booking check')
resp = resp.click('Check')
resp.form['start_time'] = '12:30'
resp.form['end_time'] = '17:30'
resp.form['presence'] = 'False'
resp.form['check-2-start_time'] = '12:30'
resp.form['check-2-end_time'] = '17:30'
resp.form['check-2-presence'] = 'False'
resp = resp.form.submit().follow()
assert len(resp.pyquery('.registrant--bar')) == 5
@ -509,20 +508,18 @@ def test_manager_partial_bookings_multiple_checks(app, admin_user):
assert resp.pyquery('.registrant--bar.check')[1].findall('time')[0].text == '12:30'
assert resp.pyquery('.registrant--bar.check')[1].findall('time')[1].text == '17:30'
resp = resp.click('Checked period', index=1)
assert 'Add second booking check' not in resp.text
resp.form['start_time'] = '11:30'
resp.form['end_time'] = ''
resp = resp.click('Check')
resp.form['check-2-start_time'] = '11:30'
resp.form['check-2-end_time'] = ''
resp = resp.form.submit()
assert 'Booking check hours overlap existing check.' in resp.text
resp.form['end_time'] = '17:30'
resp.form['check-2-end_time'] = '17:30'
resp = resp.form.submit()
assert 'Booking check hours overlap existing check.' in resp.text
resp.form['start_time'] = '12:30'
resp.form['presence'] = ''
resp.form['check-2-start_time'] = '12:30'
resp.form['check-2-presence'] = ''
resp = resp.form.submit().follow()
assert len(resp.pyquery('.registrant--bar')) == 3
@ -550,7 +547,7 @@ def test_manager_partial_bookings_incomplete_check(app, admin_user):
app = login(app)
today = start_datetime.date()
resp = app.get('/manage/agendas/%s/day/%d/%d/%d/' % (agenda.pk, today.year, today.month, today.day))
resp = resp.click('Booked period')
resp = resp.click('Check')
resp = resp.form.submit()
assert 'Both arrival and departure cannot not be empty.' in resp.text
@ -602,21 +599,20 @@ def test_manager_partial_bookings_check_subscription(check_types, app, admin_use
assert len(resp.pyquery('.registrant--bar')) == 0
assert len(resp.pyquery('.registrant--name a')) == 1
resp = resp.click('Jane Doe')
resp = resp.click('Check')
assert 'Fill with booking start time' not in resp.text
assert 'absence_check_type' not in resp.form.fields
assert resp.form['presence'].options == [
('', True, None),
('True', False, None),
('', False, None),
('True', True, None),
] # no 'False' option
assert not Booking.objects.exists()
resp.form['start_time'] = '10:00'
resp.form['end_time'] = '16:00'
resp.form['presence'] = 'True'
resp = resp.form.submit().follow()
assert len(resp.pyquery('.registrant--name a')) == 0
assert len(resp.pyquery('.registrant--name-label a')) == 0
assert len(resp.pyquery('.registrant--bar')) == 2
assert len(resp.pyquery('.registrant--bar.check.present')) == 1
assert len(resp.pyquery('.registrant--bar.computed.present')) == 1
@ -628,7 +624,7 @@ def test_manager_partial_bookings_check_subscription(check_types, app, admin_use
assert booking.user_first_name == 'Jane'
assert booking.user_last_name == 'Doe'
resp = resp.click('Checked period')
resp = resp.click('Check')
assert 'Fill with booking start time' not in resp.text
assert 'absence_check_type' not in resp.form.fields
assert resp.form['presence'].options == [
@ -709,7 +705,7 @@ def test_manager_partial_bookings_check_filters(check_types, app, admin_user):
today = start_datetime.date()
url = '/manage/agendas/%s/day/%d/%d/%d/' % (agenda.pk, today.year, today.month, today.day)
resp = app.get(url)
assert [x.text_content() for x in resp.pyquery('.registrant--name')] == [
assert [x.text_content() for x in resp.pyquery('.registrant--name-label')] == [
'User Absent Meat Foo Reason',
'Subscription Not Booked',
'User Not Checked',
@ -720,23 +716,27 @@ def test_manager_partial_bookings_check_filters(check_types, app, admin_user):
assert len(resp.pyquery('.registrant--bar.booking')) == 3
resp = app.get(url, params={'booking-status': 'booked'})
assert [x.text_content() for x in resp.pyquery('.registrant--name')] == [
assert [x.text_content() for x in resp.pyquery('.registrant--name-label')] == [
'User Absent Meat Foo Reason',
'User Not Checked',
'User Present Vegan',
]
resp = app.get(url, params={'booking-status': 'presence'})
assert [x.text_content() for x in resp.pyquery('.registrant--name')] == ['User Present Vegan']
assert [x.text_content() for x in resp.pyquery('.registrant--name-label')] == ['User Present Vegan']
resp = app.get(url, params={'booking-status': 'presence', 'extra-data-menu': 'meat'})
assert [x.text_content() for x in resp.pyquery('.registrant--name')] == []
assert [x.text_content() for x in resp.pyquery('.registrant--name-label')] == []
resp = app.get(url, params={'extra-data-menu': 'meat'})
assert [x.text_content() for x in resp.pyquery('.registrant--name')] == ['User Absent Meat Foo Reason']
assert [x.text_content() for x in resp.pyquery('.registrant--name-label')] == [
'User Absent Meat Foo Reason'
]
resp = app.get(url, params={'booking-status': 'absence::foo-reason'})
assert [x.text_content() for x in resp.pyquery('.registrant--name')] == ['User Absent Meat Foo Reason']
assert [x.text_content() for x in resp.pyquery('.registrant--name-label')] == [
'User Absent Meat Foo Reason'
]
def test_manager_partial_bookings_event_checked(app, admin_user):
@ -758,6 +758,7 @@ def test_manager_partial_bookings_event_checked(app, admin_user):
for i in range(8):
booking = Booking.objects.create(
event=event,
user_external_id='xxx',
start_time=datetime.time(8, 00),
end_time=datetime.time(10, 00),
presence_callback_url='https://example.invalid/presence/%s' % i,