manager: allow checking partial bookings separately (#81370)
gitea/chrono/pipeline/head Build queued... Details

This commit is contained in:
Valentin Deniaud 2023-10-03 11:47:52 +02:00
parent fc86701ab2
commit 1fd95681fe
4 changed files with 55 additions and 24 deletions

View File

@ -3039,12 +3039,6 @@ class Booking(models.Model):
# else take next_slot
return next_slot
def get_partial_bookings_check_url(self, agenda, event=None):
return reverse(
'chrono-manager-partial-booking-check',
kwargs={'pk': agenda.pk, 'booking_pk': self.pk},
)
def refresh_computed_times(self):
old_computed_start_time = self.computed_start_time
old_computed_end_time = self.computed_end_time
@ -4087,12 +4081,6 @@ class Subscription(models.Model):
except (VariableDoesNotExist, TemplateSyntaxError):
return
def get_partial_bookings_check_url(self, agenda, event):
return reverse(
'chrono-manager-partial-booking-subscription-check',
kwargs={'pk': agenda.pk, 'event_pk': event.pk, 'subscription_pk': self.pk},
)
class Person(models.Model):
user_external_id = models.CharField(max_length=250, unique=True)

View File

@ -50,7 +50,7 @@
<section class="partial-booking--registrant">
{% spaceless %}
<h3 class="registrant--name">
{% if allow_check %}
{% if allow_check and user.check_url %}
<a
rel="popup"
href="{{ user.check_url }}"
@ -64,15 +64,19 @@
<div class="registrant--bar-container">
{% for booking in user.bookings %}
{% if booking.start_time %}
<p
<a
class="registrant--bar clearfix booking"
title="{% trans "Booked period" %}"
style="left: {{ booking.css_left }}%; width: {{ booking.css_width }}%;"
{% if allow_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>
</p>
</a>
{% endif %}
{% endfor %}
</div>
@ -80,16 +84,20 @@
<div class="registrant--bar-container">
{% for booking in user.bookings %}
{% if booking.user_was_present is not None %}
<p
<a
class="registrant--bar clearfix check {{ booking.check_css_class }}"
title="{% trans "Checked period:" %}"
style="left: {{ booking.check_css_left }}%; width: {{ booking.check_css_width }}%;"
{% if allow_check %}
rel="popup"
href="{% url 'chrono-manager-partial-booking-check' pk=agenda.pk booking_pk=booking.pk %}"
{% endif %}
>
<strong class="sr-only">{% trans "Checked period:" %}</strong>
<time class="start-time" datetime="{{ booking.user_check_start_time|time:"H:i" }}">{{ booking.user_check_start_time|time:"H:i" }}</time>
<time class="end-time" datetime="{{ booking.user_check_end_time|time:"H:i" }}">{{ booking.user_check_end_time|time:"H:i" }}</time>
{% if booking.user_check_type_label %}<span>{{ booking.user_check_type_label }}</span>{% endif %}
</p>
</a>
{% endif %}
{% endfor %}
</div>

View File

@ -1669,11 +1669,14 @@ class AgendaDayView(EventChecksMixin, AgendaDateView, DayArchiveView):
result.user_external_id,
{
'name': result.user_name,
'check_url': result.get_partial_bookings_check_url(self.agenda, event),
'bookings': [],
},
)
if result.kind != 'booking':
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)

View File

@ -278,6 +278,36 @@ def test_manager_partial_bookings_day_view_multiple_bookings(app, admin_user, fr
assert resp.pyquery('.registrant--bar')[1].findall('time')[0].text == '15:00'
assert resp.pyquery('.registrant--bar')[1].findall('time')[1].text == '18:00'
# check first booking
resp = resp.click('Booked period', index=0)
resp.form['user_check_start_time'] = '09:30'
resp.form['user_check_end_time'] = '12:00'
resp.form['user_was_present'] = 'True'
resp = resp.form.submit().follow()
assert len(resp.pyquery('.partial-booking--registrant')) == 1
assert len(resp.pyquery('.registrant--bar')) == 4
assert len(resp.pyquery('.registrant--bar.check')) == 1
assert len(resp.pyquery('.registrant--bar.computed')) == 1
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'
# check second booking
resp = resp.click('Booked period', index=1)
resp.form['user_check_start_time'] = '15:00'
resp.form['user_check_end_time'] = '17:00'
resp.form['user_was_present'] = 'True'
resp = resp.form.submit().follow()
assert len(resp.pyquery('.partial-booking--registrant')) == 1
assert len(resp.pyquery('.registrant--bar')) == 6
assert len(resp.pyquery('.registrant--bar.check')) == 2
assert len(resp.pyquery('.registrant--bar.computed')) == 2
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'
assert resp.pyquery('.registrant--bar.check')[1].findall('time')[0].text == '15:00'
assert resp.pyquery('.registrant--bar.check')[1].findall('time')[1].text == '17:00'
@mock.patch('chrono.manager.forms.get_agenda_check_types')
def test_manager_partial_bookings_check(check_types, app, admin_user):
@ -305,7 +335,7 @@ 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('Jane Doe')
resp = resp.click('Booked period')
assert 'presence_check_type' not in resp.form.fields
assert 'absence_check_type' not in resp.form.fields
@ -358,7 +388,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('Jane Doe')
resp = resp.click('Booked period')
assert resp.form['presence_check_type'].options == [
('', True, '---------'),
('bar-reason', False, 'Bar reason'),
@ -383,7 +413,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('Jane Doe')
resp = resp.click('Booked period')
assert resp.form['presence_check_type'].value == 'bar-reason'
resp.form['user_was_present'] = 'False'
@ -395,7 +425,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('Jane Doe')
resp = resp.click('Booked period')
resp.form['user_was_present'] = ''
resp = resp.form.submit().follow()
assert len(resp.pyquery('.registrant--bar')) == 1
@ -456,6 +486,7 @@ def test_manager_partial_bookings_check_subscription(check_types, app, admin_use
resp = app.get('/manage/agendas/%s/day/%d/%d/%d/' % (agenda.pk, today.year, today.month, today.day))
assert len(resp.pyquery('.registrant--bar')) == 0
assert len(resp.pyquery('.registrant--name a')) == 1
resp = resp.click('Jane Doe')
assert 'Fill with booking start time' not in resp.text
@ -471,6 +502,7 @@ def test_manager_partial_bookings_check_subscription(check_types, app, admin_use
resp.form['user_was_present'] = 'True'
resp = resp.form.submit().follow()
assert len(resp.pyquery('.registrant--name 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
@ -482,7 +514,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('Jane Doe')
resp = resp.click('Checked period')
assert 'Fill with booking start time' not in resp.text
assert 'absence_check_type' not in resp.form.fields
assert resp.form['user_was_present'].options == [