manager: regroup partial booking check operations in one form (#82231)
This commit is contained in:
parent
8a8bea24a6
commit
b7c5d4f675
|
@ -780,6 +780,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;
|
||||
|
|
|
@ -7,28 +7,69 @@
|
|||
{% 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|time:"H:i" }} - {{ booking.end_time|time:"H:i" }}
|
||||
</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 %}
|
||||
<div
|
||||
class="booking-check-forms"
|
||||
data-fill-start_time="{{ booking.start_time|time:"H:i" }}"
|
||||
data-fill-end_time="{{ booking.end_time|time:"H:i" }}"
|
||||
{% if multiple_bookings %}
|
||||
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">
|
||||
{{ 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 %}
|
||||
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
<div class="buttons">
|
||||
<button class="submit-button">{% trans "Save" %}</button>
|
||||
<a class="cancel" href="{{ agenda.get_absolute_url }}">{% trans 'Cancel' %}</a>
|
||||
|
@ -36,28 +77,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-forms').data('fill-' + widget_id);
|
||||
$('[name="' + widget_name + '"]').val(value);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</form>
|
||||
{% if multiple_bookings %}</div>{% endif %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -83,13 +83,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 %}
|
||||
|
@ -97,33 +98,25 @@
|
|||
<div class="registrant--bar-container">
|
||||
{% for booking in user.bookings %}
|
||||
{% if booking.start_time %}
|
||||
<a
|
||||
<p
|
||||
class="registrant--bar 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 check {{ check.css_class }}"
|
||||
title="{% trans "Checked period" %}"
|
||||
style="left: {{ check.css_left }}%;{% if check.css_width %} width: {{ check.css_width }}%;{% endif %}"
|
||||
{% 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 %}
|
||||
|
@ -133,7 +126,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">
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -1693,13 +1693,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)
|
||||
|
@ -4534,61 +4538,123 @@ 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, forms=None, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['forms'] = forms or 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):
|
||||
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,
|
||||
**kwargs,
|
||||
),
|
||||
]
|
||||
|
||||
# do not show second form if checking subscription
|
||||
if booking.start_time:
|
||||
booking.check_forms.append(
|
||||
PartialBookingCheckForm(
|
||||
instance=second_check,
|
||||
prefix=self.get_prefix(booking, second_check=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)
|
||||
|
|
|
@ -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'
|
||||
|
@ -271,7 +271,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',
|
||||
|
@ -279,7 +279,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',
|
||||
|
@ -300,10 +300,22 @@ 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')
|
||||
|
||||
assert len(resp.pyquery('.pk-tabs')) == 1
|
||||
assert resp.pyquery('#tab-%s' % first_booking.pk).text() == '09:00 - 12:00'
|
||||
assert resp.pyquery('#tab-%s' % second_booking.pk).text() == '15:00 - 18:00'
|
||||
|
||||
first_prefix = 'booking-%s-' % first_booking.pk
|
||||
second_prefix = 'booking-%s-' % second_booking.pk
|
||||
|
||||
# first booking inital check value is "Present", second booking is "Not checked"
|
||||
assert resp.form[first_prefix + 'presence'].value == 'True'
|
||||
assert resp.form[second_prefix + 'presence'].value == ''
|
||||
|
||||
resp.form[first_prefix + 'start_time'] = '09:30'
|
||||
resp.form[first_prefix + 'end_time'] = '12:00'
|
||||
resp.form[first_prefix + 'presence'] = 'True'
|
||||
resp = resp.form.submit().follow()
|
||||
|
||||
assert len(resp.pyquery('.partial-booking--registrant')) == 1
|
||||
|
@ -314,10 +326,10 @@ 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')
|
||||
resp.form[second_prefix + 'start_time'] = '15:00'
|
||||
resp.form[second_prefix + 'end_time'] = '17:00'
|
||||
resp.form[second_prefix + 'presence'] = 'True'
|
||||
resp = resp.form.submit().follow()
|
||||
|
||||
assert len(resp.pyquery('.partial-booking--registrant')) == 1
|
||||
|
@ -356,20 +368,21 @@ 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 len(resp.pyquery('.pk-tabs')) == 0
|
||||
assert resp.pyquery('.booking-check-forms').attr('data-fill-start_time') == '11:00'
|
||||
assert resp.pyquery('.booking-check-forms').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'
|
||||
|
@ -414,7 +427,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'),
|
||||
|
@ -439,7 +452,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'
|
||||
|
@ -451,7 +464,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
|
||||
|
@ -463,15 +476,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
|
||||
|
@ -479,8 +492,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):
|
||||
|
@ -502,8 +515,11 @@ 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')
|
||||
|
||||
# main check inital value is "Present", second check is "Not checked"
|
||||
assert resp.form['presence'].value == 'True'
|
||||
assert resp.form['check-2-presence'].value == ''
|
||||
|
||||
resp.form['start_time'] = '09:30'
|
||||
resp.form['end_time'] = '12:00'
|
||||
|
@ -516,12 +532,12 @@ 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')
|
||||
assert 'gadjo-folded' in resp.text
|
||||
|
||||
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
|
||||
|
@ -530,20 +546,20 @@ 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 = resp.click('Check')
|
||||
assert 'gadjo-folded' not in resp.text
|
||||
|
||||
resp.form['start_time'] = '11:30'
|
||||
resp.form['end_time'] = ''
|
||||
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
|
||||
|
@ -552,6 +568,16 @@ 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('Check')
|
||||
assert 'gadjo-folded' in resp.text
|
||||
|
||||
resp.form['check-2-presence'] = 'False'
|
||||
resp.form['check-2-start_time'] = '11:30'
|
||||
resp.form['check-2-end_time'] = '11:29'
|
||||
resp = resp.form.submit()
|
||||
assert 'Arrival must be before departure.' in resp.text
|
||||
assert 'gadjo-folded' not in resp.text
|
||||
|
||||
|
||||
@pytest.mark.parametrize('subscription_only', (True, False))
|
||||
def test_manager_partial_bookings_incomplete_check(subscription_only, app, admin_user):
|
||||
|
@ -582,10 +608,10 @@ def test_manager_partial_bookings_incomplete_check(subscription_only, app, admin
|
|||
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))
|
||||
if subscription_only:
|
||||
resp = resp.click('Jane Doe')
|
||||
else:
|
||||
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
|
||||
|
||||
resp.form['start_time'] = '11:01'
|
||||
resp.form['presence'] = 'True'
|
||||
|
@ -601,7 +627,7 @@ def test_manager_partial_bookings_incomplete_check(subscription_only, app, admin
|
|||
assert resp.pyquery('.registrant--bar.check.present')[0].attrib['style'] == 'left: 30.9%;'
|
||||
assert resp.pyquery('.registrant--bar.check time').text() == '11:01'
|
||||
|
||||
resp = resp.click('Checked period')
|
||||
resp = resp.click('Check')
|
||||
resp.form['start_time'] = ''
|
||||
resp.form['end_time'] = '13:15'
|
||||
resp = resp.form.submit().follow()
|
||||
|
@ -616,7 +642,7 @@ def test_manager_partial_bookings_incomplete_check(subscription_only, app, admin
|
|||
assert resp.pyquery('.registrant--bar.check.present')[0].attrib['style'] == 'left: 0%; width: 48.08%;'
|
||||
assert resp.pyquery('.registrant--bar.check time').text() == '13:15'
|
||||
|
||||
resp = resp.click('Checked period')
|
||||
resp = resp.click('Check')
|
||||
resp.form['start_time'] = ''
|
||||
resp.form['end_time'] = ''
|
||||
resp = resp.form.submit()
|
||||
|
@ -654,21 +680,21 @@ 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()
|
||||
assert 'check-2-presence' not in resp.form.fields
|
||||
|
||||
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
|
||||
|
@ -680,7 +706,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 == [
|
||||
|
@ -761,7 +787,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',
|
||||
|
@ -772,23 +798,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):
|
||||
|
@ -810,6 +840,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,
|
||||
|
|
Loading…
Reference in New Issue