api: events check endpoint, return also times and minutes (#80973)
gitea/chrono/pipeline/head Build queued... Details

This commit is contained in:
Lauréline Guérin 2023-09-07 12:10:45 +02:00
parent 2b288340b6
commit c8d71aa997
No known key found for this signature in database
GPG Key ID: 1FAB9B9B4F93D473
2 changed files with 210 additions and 115 deletions

View File

@ -284,6 +284,29 @@ class BookingSerializer(serializers.ModelSerializer):
ret['user_presence_reason'] = (
self.instance.user_check_type_slug if self.instance.user_was_present is True else None
)
if self.instance.event.agenda.kind == 'events' and self.instance.event.agenda.partial_bookings:
self.instance.computed_start_time = self.instance.get_computed_start_time()
self.instance.computed_end_time = self.instance.get_computed_end_time()
for key in ['', 'user_check_', 'computed_']:
start_key, end_key, minutes_key = (
'%sstart_time' % key,
'%send_time' % key,
'%sduration' % key,
)
ret[start_key] = getattr(self.instance, start_key)
ret[end_key] = getattr(self.instance, end_key)
ret[minutes_key] = None
if (
getattr(self.instance, start_key) is not None
and getattr(self.instance, end_key) is not None
):
start_minutes = (
getattr(self.instance, start_key).hour * 60 + getattr(self.instance, start_key).minute
)
end_minutes = (
getattr(self.instance, end_key).hour * 60 + getattr(self.instance, end_key).minute
)
ret[minutes_key] = end_minutes - start_minutes
return ret
def _validate_check_type(self, kind, value):

View File

@ -1322,8 +1322,9 @@ def test_events_check_status(app, user):
assert resp.json['data'][0]['booking']['user_presence_reason'] == 'foo-reason'
@pytest.mark.parametrize('partial_bookings', [True, False])
@pytest.mark.freeze_time('2022-05-30 14:00')
def test_events_check_status_events(app, user):
def test_events_check_status_events(app, user, partial_bookings):
events_type = EventsType.objects.create(
label='Foo',
custom_fields=[
@ -1332,7 +1333,13 @@ def test_events_check_status_events(app, user):
{'varname': 'bool', 'label': 'Bool', 'field_type': 'bool'},
],
)
agenda = Agenda.objects.create(label='Foo', events_type=events_type)
agenda = Agenda.objects.create(
label='Foo',
events_type=events_type,
partial_bookings=partial_bookings,
invoicing_unit='half_hour',
invoicing_tolerance=10,
)
start_datetime = now()
# recurring event
recurring_event = Event.objects.create(
@ -1392,7 +1399,13 @@ def test_events_check_status_events(app, user):
user_external_id='child:42',
user_was_present=True,
user_check_type_slug='foo-reason',
start_time=datetime.time(8, 0),
end_time=datetime.time(17, 0),
user_check_start_time=datetime.time(7, 55),
user_check_end_time=datetime.time(17, 15),
)
assert booking1.get_computed_start_time() == datetime.time(8, 0)
assert booking1.get_computed_end_time() == datetime.time(17, 30)
booking2 = Booking.objects.create(
event=event, user_external_id='child:42', user_was_present=True, user_check_type_slug='foo-reason'
)
@ -1409,119 +1422,178 @@ def test_events_check_status_events(app, user):
resp = app.get(url, params=params)
assert len(ctx.captured_queries) == 5
assert resp.json['err'] == 0
assert resp.json['data'] == [
{
'event': {
'description': None,
'duration': None,
'label': 'Not Checked Event Label',
'slug': 'notchecked-event-slug',
'places': 10,
'pricing': None,
'publication_datetime': None,
'recurrence_days': None,
'recurrence_end_date': None,
'recurrence_week_interval': 1,
'start_datetime': localtime(notchecked_event.start_datetime).isoformat(),
'url': None,
'waiting_list_places': 0,
'agenda': agenda.slug,
'primary_event': None,
'check_locked': False,
'checked': False,
'invoiced': False,
'custom_field_bool': None,
'custom_field_text': '',
'custom_field_textarea': '',
},
'check_status': {'error_reason': 'event-not-checked', 'status': 'error'},
'booking': {},
},
{
'event': {
'description': None,
'duration': None,
'label': 'Event Label',
'slug': 'event-slug',
'places': 10,
'pricing': None,
'publication_datetime': None,
'recurrence_days': None,
'recurrence_end_date': None,
'recurrence_week_interval': 1,
'start_datetime': localtime(event.start_datetime).isoformat(),
'url': None,
'waiting_list_places': 0,
'agenda': agenda.slug,
'primary_event': None,
'check_locked': True,
'checked': True,
'invoiced': True,
'custom_field_bool': None,
'custom_field_text': '',
'custom_field_textarea': '',
},
'check_status': {'check_type': 'foo-reason', 'status': 'presence'},
'booking': {
'cancellation_datetime': None,
'use_color_for': None,
'creation_datetime': localtime(now()).isoformat(),
'extra_data': None,
'id': booking2.pk,
'in_waiting_list': False,
'user_absence_reason': None,
'user_email': '',
'user_first_name': '',
'user_last_name': '',
'user_phone_number': '',
'user_presence_reason': 'foo-reason',
'user_was_present': True,
'label': '',
},
},
{
'event': {
'description': None,
'duration': None,
'label': 'Recurring Event Label',
'slug': 'recurring-event-slug--2022-05-30-1600',
'places': 10,
'pricing': None,
'publication_datetime': None,
'recurrence_days': None,
'recurrence_end_date': None,
'recurrence_week_interval': 1,
'start_datetime': localtime(first_event.start_datetime).isoformat(),
'url': None,
'waiting_list_places': 0,
'agenda': agenda.slug,
'primary_event': recurring_event.slug,
'check_locked': False,
'checked': True,
'invoiced': False,
'custom_field_text': 'foo',
'custom_field_textarea': 'foo bar',
'custom_field_bool': True,
},
'check_status': {'check_type': 'foo-reason', 'status': 'presence'},
'booking': {
'cancellation_datetime': None,
'use_color_for': None,
'creation_datetime': localtime(now()).isoformat(),
'extra_data': None,
'id': booking1.pk,
'in_waiting_list': False,
'user_absence_reason': None,
'user_email': '',
'user_first_name': '',
'user_last_name': '',
'user_phone_number': '',
'user_presence_reason': 'foo-reason',
'user_was_present': True,
'label': '',
},
},
]
assert len(resp.json['data']) == 3
assert list(resp.json['data'][0].keys()) == ['event', 'check_status', 'booking']
assert resp.json['data'][0]['event'] == {
'description': None,
'duration': None,
'label': 'Not Checked Event Label',
'slug': 'notchecked-event-slug',
'places': 10,
'pricing': None,
'publication_datetime': None,
'recurrence_days': None,
'recurrence_end_date': None,
'recurrence_week_interval': 1,
'start_datetime': localtime(notchecked_event.start_datetime).isoformat(),
'url': None,
'waiting_list_places': 0,
'agenda': agenda.slug,
'primary_event': None,
'check_locked': False,
'checked': False,
'invoiced': False,
'custom_field_bool': None,
'custom_field_text': '',
'custom_field_textarea': '',
}
assert resp.json['data'][0]['check_status'] == {
'error_reason': 'event-not-checked',
'status': 'error',
}
assert resp.json['data'][0]['booking'] == {}
assert list(resp.json['data'][1].keys()) == ['event', 'check_status', 'booking']
assert resp.json['data'][1]['event'] == {
'description': None,
'duration': None,
'label': 'Event Label',
'slug': 'event-slug',
'places': 10,
'pricing': None,
'publication_datetime': None,
'recurrence_days': None,
'recurrence_end_date': None,
'recurrence_week_interval': 1,
'start_datetime': localtime(event.start_datetime).isoformat(),
'url': None,
'waiting_list_places': 0,
'agenda': agenda.slug,
'primary_event': None,
'check_locked': True,
'checked': True,
'invoiced': True,
'custom_field_bool': None,
'custom_field_text': '',
'custom_field_textarea': '',
}
assert resp.json['data'][1]['check_status'] == {
'check_type': 'foo-reason',
'status': 'presence',
}
if partial_bookings:
assert resp.json['data'][1]['booking'] == {
'cancellation_datetime': None,
'use_color_for': None,
'creation_datetime': localtime(now()).isoformat(),
'extra_data': None,
'id': booking2.pk,
'in_waiting_list': False,
'user_absence_reason': None,
'user_email': '',
'user_first_name': '',
'user_last_name': '',
'user_phone_number': '',
'user_presence_reason': 'foo-reason',
'user_was_present': True,
'label': '',
'start_time': None,
'end_time': None,
'duration': None,
'user_check_start_time': None,
'user_check_end_time': None,
'user_check_duration': None,
'computed_start_time': None,
'computed_end_time': None,
'computed_duration': None,
}
else:
assert resp.json['data'][1]['booking'] == {
'cancellation_datetime': None,
'use_color_for': None,
'creation_datetime': localtime(now()).isoformat(),
'extra_data': None,
'id': booking2.pk,
'in_waiting_list': False,
'user_absence_reason': None,
'user_email': '',
'user_first_name': '',
'user_last_name': '',
'user_phone_number': '',
'user_presence_reason': 'foo-reason',
'user_was_present': True,
'label': '',
}
assert list(resp.json['data'][2].keys()) == ['event', 'check_status', 'booking']
assert resp.json['data'][2]['event'] == {
'description': None,
'duration': None,
'label': 'Recurring Event Label',
'slug': 'recurring-event-slug--2022-05-30-1600',
'places': 10,
'pricing': None,
'publication_datetime': None,
'recurrence_days': None,
'recurrence_end_date': None,
'recurrence_week_interval': 1,
'start_datetime': localtime(first_event.start_datetime).isoformat(),
'url': None,
'waiting_list_places': 0,
'agenda': agenda.slug,
'primary_event': recurring_event.slug,
'check_locked': False,
'checked': True,
'invoiced': False,
'custom_field_text': 'foo',
'custom_field_textarea': 'foo bar',
'custom_field_bool': True,
}
assert resp.json['data'][2]['check_status'] == {
'check_type': 'foo-reason',
'status': 'presence',
}
if partial_bookings:
assert resp.json['data'][2]['booking'] == {
'cancellation_datetime': None,
'use_color_for': None,
'creation_datetime': localtime(now()).isoformat(),
'extra_data': None,
'id': booking1.pk,
'in_waiting_list': False,
'user_absence_reason': None,
'user_email': '',
'user_first_name': '',
'user_last_name': '',
'user_phone_number': '',
'user_presence_reason': 'foo-reason',
'user_was_present': True,
'label': '',
'start_time': '08:00:00',
'end_time': '17:00:00',
'duration': 540,
'user_check_start_time': '07:55:00',
'user_check_end_time': '17:15:00',
'user_check_duration': 560,
'computed_start_time': '08:00:00',
'computed_end_time': '17:30:00',
'computed_duration': 570,
}
else:
assert resp.json['data'][2]['booking'] == {
'cancellation_datetime': None,
'use_color_for': None,
'creation_datetime': localtime(now()).isoformat(),
'extra_data': None,
'id': booking1.pk,
'in_waiting_list': False,
'user_absence_reason': None,
'user_email': '',
'user_first_name': '',
'user_last_name': '',
'user_phone_number': '',
'user_presence_reason': 'foo-reason',
'user_was_present': True,
'label': '',
}
@pytest.mark.freeze_time('2022-05-30 14:00')