Projet

Général

Profil

0002-agendas-Booking.user_check_type-becomes-2-fields-slu.patch

Lauréline Guérin, 18 juin 2022 13:17

Télécharger (56,5 ko)

Voir les différences:

Subject: [PATCH 2/5] agendas: Booking.user_check_type becomes 2 fields (slug,
 label) (#66015)

 .../migrations/0129_remove_check_type.py      |  21 ++++
 .../migrations/0130_remove_check_type.py      |  46 ++++++++
 .../migrations/0131_remove_check_type.py      |  15 +++
 chrono/agendas/models.py                      |  21 ++--
 chrono/api/serializers.py                     |  17 ++-
 chrono/api/views.py                           |  13 ++-
 chrono/manager/forms.py                       |  18 ++--
 .../manager_event_check_booking_fragment.html |   4 +-
 chrono/manager/views.py                       |  70 ++++++------
 .../datetimes/test_events_multiple_agendas.py |   4 +-
 tests/api/test_booking.py                     |  90 ++++++++++------
 tests/api/test_event.py                       |  45 ++++----
 tests/manager/test_check_type.py              |  17 +--
 tests/manager/test_event.py                   | 101 +++++++++++-------
 14 files changed, 308 insertions(+), 174 deletions(-)
 create mode 100644 chrono/agendas/migrations/0129_remove_check_type.py
 create mode 100644 chrono/agendas/migrations/0130_remove_check_type.py
 create mode 100644 chrono/agendas/migrations/0131_remove_check_type.py
chrono/agendas/migrations/0129_remove_check_type.py
1
from django.db import migrations, models
2

  
3

  
4
class Migration(migrations.Migration):
5

  
6
    dependencies = [
7
        ('agendas', '0128_event_date_range_constraint'),
8
    ]
9

  
10
    operations = [
11
        migrations.AddField(
12
            model_name='booking',
13
            name='user_check_type_label',
14
            field=models.CharField(blank=True, null=True, max_length=150),
15
        ),
16
        migrations.AddField(
17
            model_name='booking',
18
            name='user_check_type_slug',
19
            field=models.CharField(blank=True, null=True, max_length=160),
20
        ),
21
    ]
chrono/agendas/migrations/0130_remove_check_type.py
1
from collections import defaultdict
2

  
3
from django.db import migrations
4

  
5

  
6
def forwards(apps, schema_editor):
7
    Booking = apps.get_model('agendas', 'Booking')
8
    for booking in Booking.objects.filter(user_check_type__isnull=False):
9
        booking.user_check_type_slug = booking.user_check_type.slug
10
        booking.user_check_type_label = booking.user_check_type.label
11
        booking.save()
12

  
13

  
14
def backwards(apps, schema_editor):
15
    Booking = apps.get_model('agendas', 'Booking')
16
    Agenda = apps.get_model('agendas', 'Agenda')
17
    check_types_by_agenda_id = defaultdict(list)
18
    for agenda in Agenda.objects.filter(kind='events'):
19
        if not agenda.check_type_group:
20
            continue
21
        for check_type in agenda.check_type_group.check_types.all():
22
            check_types_by_agenda_id[agenda.pk].append(check_type)
23
    for booking in Booking.objects.filter(user_check_type_slug__isnull=False, user_was_present__isnull=False):
24
        if booking.event.agenda_id not in check_types_by_agenda_id:
25
            # no check_types for this agenda
26
            continue
27
        for check_type in check_types_by_agenda_id[booking.event.agenda_id]:
28
            if check_type.kind == 'absence' and booking.user_was_present is True:
29
                continue
30
            if check_type.kind == 'presence' and booking.user_was_present is False:
31
                continue
32
            if check_type.slug == booking.user_check_type_slug:
33
                booking.user_check_type = check_type
34
                booking.save()
35
                break
36

  
37

  
38
class Migration(migrations.Migration):
39

  
40
    dependencies = [
41
        ('agendas', '0129_remove_check_type'),
42
    ]
43

  
44
    operations = [
45
        migrations.RunPython(forwards, reverse_code=backwards),
46
    ]
chrono/agendas/migrations/0131_remove_check_type.py
1
from django.db import migrations
2

  
3

  
4
class Migration(migrations.Migration):
5

  
6
    dependencies = [
7
        ('agendas', '0130_remove_check_type'),
8
    ]
9

  
10
    operations = [
11
        migrations.RemoveField(
12
            model_name='booking',
13
            name='user_check_type',
14
        ),
15
    ]
chrono/agendas/models.py
1958 1958
    user_email = models.EmailField(blank=True)
1959 1959
    user_phone_number = models.CharField(max_length=16, blank=True)
1960 1960
    user_was_present = models.NullBooleanField()
1961
    user_check_type = models.ForeignKey('agendas.CheckType', on_delete=models.PROTECT, blank=True, null=True)
1961
    user_check_type_slug = models.CharField(max_length=160, blank=True, null=True)
1962
    user_check_type_label = models.CharField(max_length=150, blank=True, null=True)
1962 1963
    out_of_min_delay = models.BooleanField(default=False)
1963 1964

  
1964 1965
    extra_emails = ArrayField(models.EmailField(), default=list)
......
2009 2010
            self.secondary_booking_set.update(in_waiting_list=True)
2010 2011
            self.save()
2011 2012

  
2012
    def mark_user_absence(self, check_type=None):
2013
        check_type = check_type or None
2014
        self.user_check_type = check_type
2013
    def mark_user_absence(self, check_type_slug=None, check_type_label=None):
2014
        self.user_check_type_slug = check_type_slug
2015
        self.user_check_type_label = check_type_label
2015 2016
        self.user_was_present = False
2016 2017
        with transaction.atomic():
2017
            self.secondary_booking_set.update(user_check_type=check_type)
2018
            self.secondary_booking_set.update(user_check_type_slug=check_type_slug)
2019
            self.secondary_booking_set.update(user_check_type_label=check_type_label)
2018 2020
            self.secondary_booking_set.update(user_was_present=False)
2019 2021
            self.save()
2020 2022
            self.event.set_is_checked()
2021 2023

  
2022
    def mark_user_presence(self, check_type=None):
2023
        check_type = check_type or None
2024
        self.user_check_type = check_type
2024
    def mark_user_presence(self, check_type_slug=None, check_type_label=None):
2025
        self.user_check_type_slug = check_type_slug
2026
        self.user_check_type_label = check_type_label
2025 2027
        self.user_was_present = True
2026 2028
        with transaction.atomic():
2027
            self.secondary_booking_set.update(user_check_type=check_type)
2029
            self.secondary_booking_set.update(user_check_type_slug=check_type_slug)
2030
            self.secondary_booking_set.update(user_check_type_label=check_type_label)
2028 2031
            self.secondary_booking_set.update(user_was_present=True)
2029 2032
            self.save()
2030 2033
            self.event.set_is_checked()
chrono/api/serializers.py
220 220

  
221 221
    def to_representation(self, instance):
222 222
        ret = super().to_representation(instance)
223
        check_type_slug = self.instance.user_check_type.slug if self.instance.user_check_type else ''
224
        ret['user_absence_reason'] = check_type_slug if self.instance.user_was_present is False else ''
225
        ret['user_presence_reason'] = check_type_slug if self.instance.user_was_present is True else ''
223
        ret['user_absence_reason'] = (
224
            self.instance.user_check_type_slug if self.instance.user_was_present is False else None
225
        )
226
        ret['user_presence_reason'] = (
227
            self.instance.user_check_type_slug if self.instance.user_was_present is True else None
228
        )
226 229
        return ret
227 230

  
228 231
    def _validate_check_type(self, kind, value):
......
261 264
                {'user_absence_reason': _('can not set user_absence_reason and user_presence_reason')}
262 265
            )
263 266
        if 'user_absence_reason' in attrs:
264
            attrs['user_check_type'] = attrs['user_absence_reason']
267
            check_type = attrs['user_absence_reason']
268
            attrs['user_check_type_slug'] = check_type.slug if check_type else None
269
            attrs['user_check_type_label'] = check_type.label if check_type else None
265 270
            del attrs['user_absence_reason']
266 271
        elif 'user_presence_reason' in attrs:
267
            attrs['user_check_type'] = attrs['user_presence_reason']
272
            check_type = attrs['user_presence_reason']
273
            attrs['user_check_type_slug'] = check_type.slug if check_type else None
274
            attrs['user_check_type_label'] = check_type.label if check_type else None
268 275
            del attrs['user_presence_reason']
269 276
        return attrs
270 277

  
chrono/api/views.py
2134 2134
        booking_queryset = Booking.objects.filter(
2135 2135
            event__in=events,
2136 2136
            user_external_id=user_external_id,
2137
        ).select_related('user_check_type')
2137
        )
2138 2138
        bookings_by_event_id = collections.defaultdict(list)
2139 2139
        for booking in booking_queryset:
2140 2140
            bookings_by_event_id[booking.event_id].append(booking)
......
2159 2159
                else:
2160 2160
                    check_status = {
2161 2161
                        'status': 'presence' if booking.user_was_present else 'absence',
2162
                        'check_type': booking.user_check_type.slug if booking.user_check_type else '',
2162
                        'check_type': booking.user_check_type_slug,
2163 2163
                    }
2164 2164
            data.append(
2165 2165
                {
......
2365 2365

  
2366 2366
    def filter_user_absence_reason(self, queryset, name, value):
2367 2367
        return queryset.filter(
2368
            Q(user_check_type__slug=value) | Q(user_check_type__label=value),
2369
            user_check_type__kind='absence',
2368
            Q(user_check_type_slug=value) | Q(user_check_type_label=value),
2370 2369
            user_was_present=False,
2371 2370
        )
2372 2371

  
2373 2372
    def filter_user_presence_reason(self, queryset, name, value):
2374 2373
        return queryset.filter(
2375
            Q(user_check_type__slug=value) | Q(user_check_type__label=value),
2376
            user_check_type__kind='presence',
2374
            Q(user_check_type_slug=value) | Q(user_check_type_label=value),
2377 2375
            user_was_present=True,
2378 2376
        )
2379 2377

  
......
2501 2499
            if key in request.data:
2502 2500
                secondary_bookings_update[key] = getattr(self.booking, key)
2503 2501
        if 'user_absence_reason' in request.data or 'user_presence_reason' in request.data:
2504
            secondary_bookings_update['user_check_type'] = self.booking.user_check_type
2502
            secondary_bookings_update['user_check_type_slug'] = self.booking.user_check_type_slug
2503
            secondary_bookings_update['user_check_type_label'] = self.booking.user_check_type_label
2505 2504
        if extra_data:
2506 2505
            secondary_bookings_update['extra_data'] = self.booking.extra_data
2507 2506
        if secondary_bookings_update:
chrono/manager/forms.py
443 443
        ]
444 444
        if self.agenda.check_type_group:
445 445
            status_choices += [
446
                ('presence-%s' % r.pk, _('Presence (%s)') % r.label)
446
                ('presence::%s' % r.slug, _('Presence (%s)') % r.label)
447 447
                for r in self.agenda.check_type_group.check_types.all()
448 448
                if r.kind == 'presence' and not r.disabled
449 449
            ]
450 450
        status_choices += [('absence', _('Absence'))]
451 451
        if self.agenda.check_type_group:
452 452
            status_choices += [
453
                ('absence-%s' % r.pk, _('Absence (%s)') % r.label)
453
                ('absence::%s' % r.slug, _('Absence (%s)') % r.label)
454 454
                for r in self.agenda.check_type_group.check_types.all()
455 455
                if r.kind == 'absence' and not r.disabled
456 456
            ]
......
477 477
            return queryset.filter(user_was_present=True)
478 478
        if value == 'absence':
479 479
            return queryset.filter(user_was_present=False)
480
        if value.startswith('absence-'):
481
            return queryset.filter(user_was_present=False, user_check_type=value.split('-')[1])
482
        if value.startswith('presence-'):
483
            return queryset.filter(user_was_present=True, user_check_type=value.split('-')[1])
480
        if value.startswith('absence::'):
481
            return queryset.filter(user_was_present=False, user_check_type_slug=value.split('::')[1])
482
        if value.startswith('presence::'):
483
            return queryset.filter(user_was_present=True, user_check_type_slug=value.split('::')[1])
484 484
        return queryset
485 485

  
486 486
    def do_nothing(self, queryset, name, value):
......
506 506
        super().__init__(*args, **kwargs)
507 507
        if agenda.check_type_group:
508 508
            self.fields['check_type'].choices = [('', '---------')] + [
509
                (r.pk, r.label)
509
                (r.slug, r.label)
510 510
                for r in agenda.check_type_group.check_types.all()
511 511
                if r.kind == 'absence' and not r.disabled
512 512
            ]
......
520 520
        super().__init__(*args, **kwargs)
521 521
        if agenda.check_type_group:
522 522
            self.fields['check_type'].choices = [('', '---------')] + [
523
                (r.pk, r.label)
523
                (r.slug, r.label)
524 524
                for r in agenda.check_type_group.check_types.all()
525 525
                if r.kind == 'presence' and not r.disabled
526 526
            ]
......
1322 1322
        super().__init__(*args, **kwargs)
1323 1323
        if not CheckTypeGroup.objects.exists():
1324 1324
            del self.fields['check_type_group']
1325
        elif Booking.objects.filter(event__agenda=self.instance, user_check_type__isnull=False).exists():
1325
        elif Booking.objects.filter(event__agenda=self.instance, user_check_type_slug__isnull=False).exists():
1326 1326
            # not possible to update check_type_group if bookings with non null check_type exist
1327 1327
            del self.fields['check_type_group']
1328 1328

  
chrono/manager/templates/chrono/manager_event_check_booking_fragment.html
3 3
<td class="booking-username main-list">{{ booking.get_user_block }}{% if booking.places_count > 1 %} ({{ booking.places_count }} {% trans "places" %}){% endif %}</td>
4 4
<td class="booking-status {% if booking.user_was_present is None %}without-status{% endif %}">
5 5
  {{ booking.user_was_present|yesno:_('Present,Absent,-') }}
6
  {% if booking.user_was_present is not None and booking.user_check_type %}
7
    ({{ booking.user_check_type }})
6
  {% if booking.user_was_present is not None and booking.user_check_type_label %}
7
    ({{ booking.user_check_type_label }})
8 8
  {% endif %}
9 9
</td>
10 10
{% if not event.checked or not agenda.disable_check_update %}
chrono/manager/views.py
719 719
            raise PermissionDenied()
720 720
        return super().dispatch(request, *args, **kwargs)
721 721

  
722
    def get_context_data(self, **kwargs):
723
        context = super().get_context_data(**kwargs)
724
        context['cannot_delete'] = Booking.objects.filter(user_check_type__group=self.get_object()).exists()
725
        context['cannot_delete_msg'] = _(
726
            'Can not delete this check type group: a check type of this group is set on some existing bookings.'
727
        )
728
        return context
729

  
730
    def delete(self, request, *args, **kwargs):
731
        if Booking.objects.filter(user_check_type__group=self.get_object()).exists():
732
            raise Http404
733
        return super().delete(request, *args, **kwargs)
734

  
735 722
    def get_success_url(self):
736 723
        return reverse('chrono-manager-check-type-list')
737 724

  
......
802 789

  
803 790
    def get_context_data(self, **kwargs):
804 791
        context = super().get_context_data(**kwargs)
805
        context['is_used'] = Booking.objects.filter(user_check_type=self.get_object()).exists()
792
        context['is_used'] = Booking.objects.filter(user_check_type_slug=self.get_object().slug).exists()
806 793
        return context
807 794

  
808 795
    def get_success_url(self):
......
827 814

  
828 815
    def get_context_data(self, **kwargs):
829 816
        context = super().get_context_data(**kwargs)
830
        context['cannot_delete'] = Booking.objects.filter(user_check_type=self.get_object()).exists()
817
        context['cannot_delete'] = Booking.objects.filter(
818
            user_check_type_slug=self.get_object().slug
819
        ).exists()
831 820
        context['cannot_delete_msg'] = _(
832 821
            'Can not delete this check type: it is set on some existing bookings.'
833 822
        )
834 823
        return context
835 824

  
836 825
    def delete(self, request, *args, **kwargs):
837
        if Booking.objects.filter(user_check_type=self.get_object()).exists():
826
        if Booking.objects.filter(user_check_type_slug=self.get_object().slug).exists():
838 827
            raise Http404
839 828
        return super().delete(request, *args, **kwargs)
840 829

  
......
2399 2388
        booking_qs_kwargs = {}
2400 2389
        if not self.agenda.subscriptions.exists():
2401 2390
            booking_qs_kwargs = {'cancellation_datetime__isnull': True}
2402
        booking_qs = event.booking_set.prefetch_related('user_check_type')
2391
        booking_qs = event.booking_set
2403 2392
        booked_qs = booking_qs.filter(
2404 2393
            in_waiting_list=False, primary_booking__isnull=True, **booking_qs_kwargs
2405 2394
        )
......
2445 2434
                booked_without_status = True
2446 2435
            booking.absence_form = BookingCheckAbsenceForm(
2447 2436
                agenda=self.agenda,
2448
                initial={'check_type': booking.user_check_type_id},
2437
                initial={'check_type': booking.user_check_type_slug},
2449 2438
            )
2450 2439
            booking.presence_form = BookingCheckPresenceForm(
2451 2440
                agenda=self.agenda,
2452
                initial={'check_type': booking.user_check_type_id},
2441
                initial={'check_type': booking.user_check_type_slug},
2453 2442
            )
2454 2443
            booking.kind = 'booking'
2455 2444
            results.append(booking)
......
2507 2496
            user_was_present__isnull=True,
2508 2497
        )
2509 2498

  
2499
    def get_check_type(self, kind):
2500
        form = self.get_form()
2501
        check_type = None
2502
        if form.is_valid() and form.cleaned_data['check_type']:
2503
            check_type = CheckType.objects.filter(
2504
                slug=form.cleaned_data['check_type'], kind=kind, group=self.agenda.check_type_group
2505
            ).first()
2506
        return check_type
2507

  
2510 2508
    def response(self, request):
2511 2509
        return HttpResponseRedirect(
2512 2510
            reverse(
......
2525 2523
        return kwargs
2526 2524

  
2527 2525
    def post(self, request, *args, **kwargs):
2528
        form = self.get_form()
2529 2526
        qs_kwargs = {}
2530
        if form.is_valid():
2531
            qs_kwargs['user_check_type'] = form.cleaned_data['check_type']
2527
        check_type = self.get_check_type(kind='presence')
2528
        qs_kwargs['user_check_type_slug'] = check_type.slug if check_type else None
2529
        qs_kwargs['user_check_type_label'] = check_type.label if check_type else None
2532 2530
        bookings = self.get_bookings()
2533 2531
        bookings.update(user_was_present=True, **qs_kwargs)
2534 2532
        self.event.set_is_checked()
......
2547 2545
        return kwargs
2548 2546

  
2549 2547
    def post(self, request, *args, **kwargs):
2550
        form = self.get_form()
2551 2548
        qs_kwargs = {}
2552
        if form.is_valid():
2553
            qs_kwargs['user_check_type'] = form.cleaned_data['check_type']
2549
        check_type = self.get_check_type(kind='absence')
2550
        qs_kwargs['user_check_type_slug'] = check_type.slug if check_type else None
2551
        qs_kwargs['user_check_type_label'] = check_type.label if check_type else None
2554 2552
        bookings = self.get_bookings()
2555 2553
        bookings.update(user_was_present=False, **qs_kwargs)
2556 2554
        self.event.set_is_checked()
......
3261 3259
            primary_booking__isnull=True,
3262 3260
        )
3263 3261

  
3264
    def get_check_type(self):
3262
    def get_check_type(self, kind):
3265 3263
        form = self.get_form()
3266 3264
        check_type = None
3267 3265
        if form.is_valid() and form.cleaned_data['check_type']:
3268
            check_type = CheckType.objects.get(pk=form.cleaned_data['check_type'])
3266
            check_type = CheckType.objects.filter(
3267
                slug=form.cleaned_data['check_type'], kind=kind, group=self.agenda.check_type_group
3268
            ).first()
3269 3269
        return check_type
3270 3270

  
3271 3271
    def response(self, request, booking):
3272 3272
        if request.is_ajax():
3273 3273
            booking.absence_form = BookingCheckAbsenceForm(
3274
                agenda=self.agenda, initial={'check_type': booking.user_check_type_id}
3274
                agenda=self.agenda, initial={'check_type': booking.user_check_type_slug}
3275 3275
            )
3276 3276
            booking.presence_form = BookingCheckPresenceForm(
3277
                agenda=self.agenda, initial={'check_type': booking.user_check_type_id}
3277
                agenda=self.agenda, initial={'check_type': booking.user_check_type_slug}
3278 3278
            )
3279 3279
            return render(
3280 3280
                request,
......
3299 3299

  
3300 3300
    def post(self, request, *args, **kwargs):
3301 3301
        booking = self.get_booking(**kwargs)
3302
        booking.mark_user_presence(check_type=self.get_check_type())
3302
        check_type = self.get_check_type(kind='presence')
3303
        booking.mark_user_presence(
3304
            check_type_slug=check_type.slug if check_type else None,
3305
            check_type_label=check_type.label if check_type else None,
3306
        )
3303 3307
        return self.response(request, booking)
3304 3308

  
3305 3309

  
......
3316 3320

  
3317 3321
    def post(self, request, *args, **kwargs):
3318 3322
        booking = self.get_booking(**kwargs)
3319
        booking.mark_user_absence(check_type=self.get_check_type())
3323
        check_type = self.get_check_type(kind='absence')
3324
        booking.mark_user_absence(
3325
            check_type_slug=check_type.slug if check_type else None,
3326
            check_type_label=check_type.label if check_type else None,
3327
        )
3320 3328
        return self.response(request, booking)
3321 3329

  
3322 3330

  
tests/api/datetimes/test_events_multiple_agendas.py
1242 1242
        event=event_absence_with_reason,
1243 1243
        user_external_id='xxx',
1244 1244
        user_was_present=False,
1245
        user_check_type=check_type_absence,
1245
        user_check_type_slug=check_type_absence.slug,
1246 1246
    )
1247 1247
    event_presence = Event.objects.create(
1248 1248
        slug='event-presence',
......
1261 1261
        event=event_presence_with_reason,
1262 1262
        user_external_id='xxx',
1263 1263
        user_was_present=True,
1264
        user_check_type=check_type_presence,
1264
        user_check_type_slug=check_type_presence.slug,
1265 1265
    )
1266 1266
    event_booked_future = Event.objects.create(
1267 1267
        slug='event-booked-future',
tests/api/test_booking.py
151 151
            'user_email': '',
152 152
            'user_phone_number': '',
153 153
            'user_was_present': None,
154
            'user_absence_reason': '',
155
            'user_presence_reason': '',
154
            'user_absence_reason': None,
155
            'user_presence_reason': None,
156 156
            'color': None,
157 157
            'extra_data': None,
158 158
            'cancellation_datetime': None,
......
166 166
            'user_email': '',
167 167
            'user_phone_number': '',
168 168
            'user_was_present': None,
169
            'user_absence_reason': '',
170
            'user_presence_reason': '',
169
            'user_absence_reason': None,
170
            'user_presence_reason': None,
171 171
            'color': None,
172 172
            'extra_data': None,
173 173
            'event': resp.json['data'][1]['event'],
......
182 182
            'user_email': '',
183 183
            'user_phone_number': '',
184 184
            'user_was_present': None,
185
            'user_absence_reason': '',
186
            'user_presence_reason': '',
185
            'user_absence_reason': None,
186
            'user_presence_reason': None,
187 187
            'color': None,
188 188
            'extra_data': None,
189 189
            'event': resp.json['data'][1]['event'],
......
333 333
    )
334 334
    Booking.objects.create(event=event, user_external_id='42', user_was_present=False)
335 335
    booking2 = Booking.objects.create(
336
        event=event, user_external_id='42', user_was_present=False, user_check_type=check_type_absence
336
        event=event,
337
        user_external_id='42',
338
        user_was_present=False,
339
        user_check_type_slug=check_type_absence.slug,
340
        user_check_type_label=check_type_absence.label,
337 341
    )
338 342
    Booking.objects.create(
339
        event=event, user_external_id='42', user_was_present=False, user_check_type=check_type_presence
343
        event=event,
344
        user_external_id='42',
345
        user_was_present=True,
346
        user_check_type_slug=check_type_presence.slug,
347
        user_check_type_label=check_type_presence.label,
340 348
    )
341 349

  
342 350
    app.authorization = ('Basic', ('john.doe', 'password'))
......
376 384
    )
377 385
    Booking.objects.create(event=event, user_external_id='42', user_was_present=True)
378 386
    booking2 = Booking.objects.create(
379
        event=event, user_external_id='42', user_was_present=True, user_check_type=check_type_presence
387
        event=event,
388
        user_external_id='42',
389
        user_was_present=True,
390
        user_check_type_slug=check_type_presence.slug,
391
        user_check_type_label=check_type_presence.label,
380 392
    )
381 393
    Booking.objects.create(
382
        event=event, user_external_id='42', user_was_present=True, user_check_type=check_type_absence
394
        event=event,
395
        user_external_id='42',
396
        user_was_present=False,
397
        user_check_type_slug=check_type_absence.slug,
398
        user_check_type_label=check_type_absence.label,
383 399
    )
384 400

  
385 401
    app.authorization = ('Basic', ('john.doe', 'password'))
......
483 499
    )
484 500
    agenda = Agenda.objects.create(label='Foo bar', kind='events')
485 501
    event = Event.objects.create(agenda=agenda, start_datetime=now(), places=10)
486
    booking = Booking.objects.create(event=event, user_was_present=flag, user_check_type=check_type)
502
    booking = Booking.objects.create(event=event, user_was_present=flag, user_check_type_slug=check_type.slug)
487 503

  
488 504
    app.authorization = ('Basic', ('john.doe', 'password'))
489 505
    resp = app.get('/api/booking/%s/' % booking.pk)
490 506
    assert resp.json['booking_id'] == booking.pk
491 507
    assert resp.json['user_was_present'] == flag
492
    assert resp.json['user_absence_reason'] == ('foo-bar' if flag is False else '')
493
    assert resp.json['user_presence_reason'] == ('foo-bar' if flag is True else '')
508
    assert resp.json['user_absence_reason'] == ('foo-bar' if flag is False else None)
509
    assert resp.json['user_presence_reason'] == ('foo-bar' if flag is True else None)
494 510

  
495 511

  
496 512
@pytest.mark.parametrize('flag', [True, False])
......
663 679
    # it works with label
664 680
    app.patch_json('/api/booking/%s/' % booking.pk, params={'user_absence_reason': 'Foo bar'})
665 681
    booking.refresh_from_db()
666
    assert booking.user_check_type == check_type_absence
682
    assert booking.user_check_type_slug == check_type_absence.slug
683
    assert booking.user_check_type_label == check_type_absence.label
667 684

  
668 685
    # disabled
669 686
    resp = app.patch_json(
......
677 694
    # reset
678 695
    app.patch_json('/api/booking/%s/' % booking.pk, params={'user_absence_reason': ''})
679 696
    booking.refresh_from_db()
680
    assert booking.user_check_type is None
697
    assert booking.user_check_type_slug is None
698
    assert booking.user_check_type_label is None
681 699
    app.patch_json('/api/booking/%s/' % booking.pk, params={'user_absence_reason': None})
682 700
    booking.refresh_from_db()
683
    assert booking.user_check_type is None
701
    assert booking.user_check_type_slug is None
702
    assert booking.user_check_type_label is None
684 703

  
685 704
    # make secondary bookings
686 705
    Booking.objects.create(event=event, primary_booking=booking, user_was_present=False)
......
691 710
    # it works also with slug
692 711
    app.patch_json('/api/booking/%s/' % booking.pk, params={'user_absence_reason': check_type_absence.slug})
693 712
    booking.refresh_from_db()
694
    assert booking.user_check_type == check_type_absence
713
    assert booking.user_check_type_slug == check_type_absence.slug
714
    assert booking.user_check_type_label == check_type_absence.label
695 715
    # all secondary bookings are updated
696
    assert list(booking.secondary_booking_set.values_list('user_check_type', flat=True)) == [
697
        check_type_absence.pk,
698
        check_type_absence.pk,
716
    assert list(booking.secondary_booking_set.values_list('user_check_type_slug', flat=True)) == [
717
        check_type_absence.slug,
718
        check_type_absence.slug,
699 719
    ]
700 720
    other_booking.refresh_from_db()
701
    assert other_booking.user_check_type is None  # not changed
721
    assert other_booking.user_check_type_slug is None  # not changed
722
    assert other_booking.user_check_type_label is None  # not changed
702 723

  
703 724
    # user_was_present is True, can not set user_absence_reason
704 725
    Booking.objects.update(user_was_present=True)
......
716 737
    assert resp.json['err'] == 0
717 738
    booking.refresh_from_db()
718 739
    assert booking.user_was_present is False
719
    assert booking.user_check_type == check_type_absence
740
    assert booking.user_check_type_slug == check_type_absence.slug
741
    assert booking.user_check_type_label == check_type_absence.label
720 742

  
721 743
    # mark the event as checked
722 744
    event.checked = True
......
783 805
    # it works with label
784 806
    app.patch_json('/api/booking/%s/' % booking.pk, params={'user_presence_reason': 'Foo bar'})
785 807
    booking.refresh_from_db()
786
    assert booking.user_check_type == check_type_presence
808
    assert booking.user_check_type_slug == check_type_presence.slug
809
    assert booking.user_check_type_label == check_type_presence.label
787 810

  
788 811
    # disabled
789 812
    resp = app.patch_json(
......
797 820
    # reset
798 821
    app.patch_json('/api/booking/%s/' % booking.pk, params={'user_presence_reason': ''})
799 822
    booking.refresh_from_db()
800
    assert booking.user_check_type is None
823
    assert booking.user_check_type_slug is None
824
    assert booking.user_check_type_label is None
801 825
    app.patch_json('/api/booking/%s/' % booking.pk, params={'user_presence_reason': None})
802 826
    booking.refresh_from_db()
803
    assert booking.user_check_type is None
827
    assert booking.user_check_type_slug is None
828
    assert booking.user_check_type_label is None
804 829

  
805 830
    # make secondary bookings
806 831
    Booking.objects.create(event=event, primary_booking=booking, user_was_present=True)
......
811 836
    # it works also with slug
812 837
    app.patch_json('/api/booking/%s/' % booking.pk, params={'user_presence_reason': check_type_presence.slug})
813 838
    booking.refresh_from_db()
814
    assert booking.user_check_type == check_type_presence
839
    assert booking.user_check_type_slug == check_type_presence.slug
840
    assert booking.user_check_type_label == check_type_presence.label
815 841
    # all secondary bookings are updated
816
    assert list(booking.secondary_booking_set.values_list('user_check_type', flat=True)) == [
817
        check_type_presence.pk,
818
        check_type_presence.pk,
842
    assert list(booking.secondary_booking_set.values_list('user_check_type_slug', flat=True)) == [
843
        check_type_presence.slug,
844
        check_type_presence.slug,
819 845
    ]
820 846
    other_booking.refresh_from_db()
821
    assert other_booking.user_check_type is None  # not changed
847
    assert other_booking.user_check_type_slug is None  # not changed
848
    assert other_booking.user_check_type_label is None  # not changed
822 849

  
823 850
    # user_was_present is False, can not set user_presence_reason
824 851
    Booking.objects.update(user_was_present=False)
......
836 863
    assert resp.json['err'] == 0
837 864
    booking.refresh_from_db()
838 865
    assert booking.user_was_present is True
839
    assert booking.user_check_type == check_type_presence
866
    assert booking.user_check_type_slug == check_type_presence.slug
867
    assert booking.user_check_type_label == check_type_presence.label
840 868

  
841 869
    # mark the event as checked
842 870
    event.checked = True
tests/api/test_event.py
5 5
from django.test.utils import CaptureQueriesContext
6 6
from django.utils.timezone import localtime, make_aware, now
7 7

  
8
from chrono.agendas.models import Agenda, Booking, CheckType, CheckTypeGroup, Event, EventsType, Subscription
8
from chrono.agendas.models import Agenda, Booking, Event, EventsType, Subscription
9 9

  
10 10
pytestmark = pytest.mark.django_db
11 11

  
......
1017 1017
    assert len(resp.json['data']) == 1
1018 1018
    assert resp.json['data'][0]['check_status'] == {
1019 1019
        'status': 'absence',
1020
        'check_type': '',
1020
        'check_type': None,
1021 1021
    }
1022 1022
    assert resp.json['data'][0]['booking']['user_was_present'] is False
1023
    assert resp.json['data'][0]['booking']['user_absence_reason'] == ''
1024
    assert resp.json['data'][0]['booking']['user_presence_reason'] == ''
1023
    assert resp.json['data'][0]['booking']['user_absence_reason'] is None
1024
    assert resp.json['data'][0]['booking']['user_presence_reason'] is None
1025 1025

  
1026 1026
    # absence with check type
1027
    group = CheckTypeGroup.objects.create(label='Foo bar')
1028
    check_type = CheckType.objects.create(label='Foo reason', group=group, kind='absence')
1029
    booking.user_check_type = check_type
1027
    booking.user_check_type_slug = 'foo-reason'
1030 1028
    booking.save()
1031 1029
    resp = app.get(url, params=params)
1032 1030
    assert resp.json['err'] == 0
......
1037 1035
    }
1038 1036
    assert resp.json['data'][0]['booking']['user_was_present'] is False
1039 1037
    assert resp.json['data'][0]['booking']['user_absence_reason'] == 'foo-reason'
1040
    assert resp.json['data'][0]['booking']['user_presence_reason'] == ''
1038
    assert resp.json['data'][0]['booking']['user_presence_reason'] is None
1041 1039

  
1042 1040
    # presence
1043
    booking.user_check_type = None
1041
    booking.user_check_type_slug = None
1044 1042
    booking.user_was_present = True
1045 1043
    booking.save()
1046 1044
    resp = app.get(url, params=params)
......
1048 1046
    assert len(resp.json['data']) == 1
1049 1047
    assert resp.json['data'][0]['check_status'] == {
1050 1048
        'status': 'presence',
1051
        'check_type': '',
1049
        'check_type': None,
1052 1050
    }
1053 1051
    assert resp.json['data'][0]['booking']['user_was_present'] is True
1054
    assert resp.json['data'][0]['booking']['user_absence_reason'] == ''
1055
    assert resp.json['data'][0]['booking']['user_presence_reason'] == ''
1052
    assert resp.json['data'][0]['booking']['user_absence_reason'] is None
1053
    assert resp.json['data'][0]['booking']['user_presence_reason'] is None
1056 1054

  
1057 1055
    # presence with check type
1058
    check_type.kind = 'presence'
1059
    check_type.save()
1060
    booking.user_check_type = check_type
1056
    booking.user_check_type_slug = 'foo-reason'
1061 1057
    booking.save()
1062 1058
    resp = app.get(url, params=params)
1063 1059
    assert resp.json['err'] == 0
......
1067 1063
        'check_type': 'foo-reason',
1068 1064
    }
1069 1065
    assert resp.json['data'][0]['booking']['user_was_present'] is True
1070
    assert resp.json['data'][0]['booking']['user_absence_reason'] == ''
1066
    assert resp.json['data'][0]['booking']['user_absence_reason'] is None
1071 1067
    assert resp.json['data'][0]['booking']['user_presence_reason'] == 'foo-reason'
1072 1068

  
1073 1069

  
......
1081 1077
            {'varname': 'bool', 'label': 'Bool', 'field_type': 'bool'},
1082 1078
        ],
1083 1079
    )
1084
    group = CheckTypeGroup.objects.create(label='Foo bar')
1085
    check_type = CheckType.objects.create(label='Foo reason', group=group, kind='absence')
1086 1080
    agenda = Agenda.objects.create(label='Foo', events_type=events_type)
1087 1081
    start_datetime = now()
1088 1082
    # recurring event
......
1137 1131
        date_end=datetime.date(year=2022, month=9, day=1),
1138 1132
    )
1139 1133
    booking1 = Booking.objects.create(
1140
        event=first_event, user_external_id='child:42', user_was_present=True, user_check_type=check_type
1134
        event=first_event,
1135
        user_external_id='child:42',
1136
        user_was_present=True,
1137
        user_check_type_slug='foo-reason',
1141 1138
    )
1142 1139
    booking2 = Booking.objects.create(
1143
        event=event, user_external_id='child:42', user_was_present=True, user_check_type=check_type
1140
        event=event, user_external_id='child:42', user_was_present=True, user_check_type_slug='foo-reason'
1144 1141
    )
1145 1142

  
1146 1143
    app.authorization = ('Basic', ('john.doe', 'password'))
......
1209 1206
                'extra_data': None,
1210 1207
                'id': booking2.pk,
1211 1208
                'in_waiting_list': False,
1212
                'user_absence_reason': '',
1209
                'user_absence_reason': None,
1213 1210
                'user_email': '',
1214 1211
                'user_first_name': '',
1215 1212
                'user_last_name': '',
1216 1213
                'user_phone_number': '',
1217
                'user_presence_reason': check_type.slug,
1214
                'user_presence_reason': 'foo-reason',
1218 1215
                'user_was_present': True,
1219 1216
            },
1220 1217
        },
......
1247 1244
                'extra_data': None,
1248 1245
                'id': booking1.pk,
1249 1246
                'in_waiting_list': False,
1250
                'user_absence_reason': '',
1247
                'user_absence_reason': None,
1251 1248
                'user_email': '',
1252 1249
                'user_first_name': '',
1253 1250
                'user_last_name': '',
1254 1251
                'user_phone_number': '',
1255
                'user_presence_reason': check_type.slug,
1252
                'user_presence_reason': 'foo-reason',
1256 1253
                'user_was_present': True,
1257 1254
            },
1258 1255
        },
tests/manager/test_check_type.py
83 83
    assert CheckTypeGroup.objects.exists() is False
84 84
    assert CheckType.objects.exists() is False
85 85

  
86
    # check_type is used
87
    group = CheckTypeGroup.objects.create(label='Foo bar')
88
    check_type = CheckType.objects.create(label='Foo reason', group=group)
89
    Booking.objects.update(user_check_type=check_type)
90
    resp = app.get('/manage/check-type/group/%s/delete/' % group.pk)
91
    assert (
92
        'Can not delete this check type group: a check type of this group is set on some existing bookings.'
93
        in resp
94
    )
95
    resp.form.submit(status=404)
96

  
97 86

  
98 87
def test_delete_group_as_manager(app, manager_user, agenda_with_restrictions):
99 88
    group = CheckTypeGroup.objects.create(label='Foo bar')
......
169 158
    assert check_type.disabled is True
170 159

  
171 160
    # check_type is used
172
    Booking.objects.update(user_check_type=check_type)
161
    Booking.objects.update(user_check_type_slug=check_type.slug)
173 162
    resp = app.get('/manage/check-type/group/%s/%s/edit/' % (group.pk, check_type.pk))
174 163
    assert 'This check type is set on some existing bookings, modify it with caution.' in resp
175 164

  
......
201 190

  
202 191
    # check_type is used
203 192
    check_type = CheckType.objects.create(label='Foo reason', group=group)
204
    Booking.objects.update(user_check_type=check_type)
193
    Booking.objects.update(user_check_type_slug=check_type.slug)
205 194
    resp = app.get('/manage/check-type/group/%s/%s/delete/' % (group.pk, check_type.pk))
206 195
    assert 'Can not delete this check type: it is set on some existing bookings.' in resp
207 196
    resp.form.submit(status=404)
......
259 248
    assert 'Check type group: Foo bar' in resp
260 249

  
261 250
    # cannot change check_type group booking with non null check_type exists
262
    booking.user_check_type = check_type
251
    booking.user_check_type_slug = check_type.slug
263 252
    booking.save()
264 253
    resp = app.get('/manage/agendas/%s/check-options' % agenda.pk)
265 254
    assert 'check_type_group' not in resp.context['form'].fields
tests/manager/test_event.py
1707 1707
        user_last_name='foo-none bar-val2 reason-foo',
1708 1708
        extra_data={'bar': 'val2'},
1709 1709
        user_was_present=False,
1710
        user_check_type=check_type_absence,
1710
        user_check_type_slug=check_type_absence.slug,
1711 1711
    )
1712 1712
    Booking.objects.create(
1713 1713
        event=event,
......
1716 1716
        user_last_name='foo-none bar-val2 reason-bar',
1717 1717
        extra_data={'bar': 'val2'},
1718 1718
        user_was_present=True,
1719
        user_check_type=check_type_presence,
1719
        user_check_type_slug=check_type_presence.slug,
1720 1720
    )
1721 1721
    Booking.objects.create(
1722 1722
        event=event,
......
1725 1725
        user_last_name='foo-none bar-val2 cancelled-absence',
1726 1726
        extra_data={'bar': 'val2'},
1727 1727
        user_was_present=False,
1728
        user_check_type=check_type_absence,
1728
        user_check_type_slug=check_type_absence.slug,
1729 1729
        cancellation_datetime=now(),
1730 1730
    )
1731 1731
    Booking.objects.create(
......
1735 1735
        user_last_name='foo-none bar-val2 cancelled-presence',
1736 1736
        extra_data={'bar': 'val2'},
1737 1737
        user_was_present=True,
1738
        user_check_type=check_type_presence,
1738
        user_check_type_slug=check_type_presence.slug,
1739 1739
        cancellation_datetime=now(),
1740 1740
    )
1741 1741

  
......
1816 1816
        assert 'Subscription foo-val2 bar-val1' in resp
1817 1817
        assert 'Subscription foo-val1 bar-val2' in resp
1818 1818
        assert 'Subscription foo-none bar-val2' in resp
1819
        assert len(resp.pyquery.find('input[value=absence-%s]' % check_type_absence_disabled.pk)) == 0
1820
        assert len(resp.pyquery.find('input[value=absence-%s]' % check_type_presence_disabled.pk)) == 0
1819
        assert len(resp.pyquery.find('input[value=absence-%s]' % check_type_absence_disabled.slug)) == 0
1820
        assert len(resp.pyquery.find('input[value=absence-%s]' % check_type_presence_disabled.slug)) == 0
1821 1821

  
1822 1822
    with CaptureQueriesContext(connection) as ctx:
1823 1823
        resp = app.get(
1824 1824
            '/manage/agendas/%s/events/%s/check' % (agenda.pk, event.pk), params={'extra-data-foo': 'val1'}
1825 1825
        )
1826
        assert len(ctx.captured_queries) == 13
1826
        assert len(ctx.captured_queries) == 12
1827 1827
    assert 'User none' not in resp
1828 1828
    assert 'User empty' not in resp
1829 1829
    assert 'User foo-val1 bar-none presence' in resp
......
1996 1996

  
1997 1997
    resp = app.get(
1998 1998
        '/manage/agendas/%s/events/%s/check' % (agenda.pk, event.pk),
1999
        params={'booking-status': 'absence-%s' % check_type_absence.pk},
1999
        params={'booking-status': 'absence::%s' % check_type_absence.slug},
2000 2000
    )
2001 2001
    assert 'User none' not in resp
2002 2002
    assert 'User empty' not in resp
......
2016 2016

  
2017 2017
    resp = app.get(
2018 2018
        '/manage/agendas/%s/events/%s/check' % (agenda.pk, event.pk),
2019
        params={'booking-status': 'presence-%s' % check_type_presence.pk},
2019
        params={'booking-status': 'presence::%s' % check_type_presence.slug},
2020 2020
    )
2021 2021
    assert 'User none' not in resp
2022 2022
    assert 'User empty' not in resp
......
2107 2107
    assert resp.pyquery.find('td.booking-actions button[disabled]')[0].text == 'Presence'
2108 2108
    booking.refresh_from_db()
2109 2109
    assert booking.user_was_present is True
2110
    assert booking.user_check_type is None
2110
    assert booking.user_check_type_slug is None
2111
    assert booking.user_check_type_label is None
2111 2112
    secondary_booking.refresh_from_db()
2112 2113
    assert secondary_booking.user_was_present is True
2113
    assert secondary_booking.user_check_type is None
2114
    assert secondary_booking.user_check_type_slug is None
2115
    assert secondary_booking.user_check_type_label is None
2114 2116
    event.refresh_from_db()
2115 2117
    assert event.checked is False
2116 2118

  
......
2127 2129
    assert resp.pyquery.find('td.booking-actions button[disabled]')[0].text == 'Absence'
2128 2130
    booking.refresh_from_db()
2129 2131
    assert booking.user_was_present is False
2130
    assert booking.user_check_type is None
2132
    assert booking.user_check_type_slug is None
2133
    assert booking.user_check_type_label is None
2131 2134
    secondary_booking.refresh_from_db()
2132 2135
    assert secondary_booking.user_was_present is False
2133
    assert secondary_booking.user_check_type is None
2136
    assert secondary_booking.user_check_type_slug is None
2137
    assert secondary_booking.user_check_type_label is None
2134 2138
    event.refresh_from_db()
2135 2139
    assert event.checked is True
2136 2140

  
......
2150 2154
    # set as absent with check_type
2151 2155
    resp = app.post(
2152 2156
        '/manage/agendas/%s/bookings/%s/absence' % (agenda.pk, booking.pk),
2153
        params={'csrfmiddlewaretoken': token, 'check_type': check_type_absence.pk},
2157
        params={'csrfmiddlewaretoken': token, 'check_type': check_type_absence.slug},
2154 2158
    ).follow()
2155 2159
    assert 'Foo reason' in resp
2156 2160
    booking.refresh_from_db()
2157 2161
    assert booking.user_was_present is False
2158
    assert booking.user_check_type == check_type_absence
2162
    assert booking.user_check_type_slug == check_type_absence.slug
2163
    assert booking.user_check_type_label == check_type_absence.label
2159 2164
    secondary_booking.refresh_from_db()
2160 2165
    assert secondary_booking.user_was_present is False
2161
    assert secondary_booking.user_check_type == check_type_absence
2166
    assert secondary_booking.user_check_type_slug == check_type_absence.slug
2167
    assert secondary_booking.user_check_type_label == check_type_absence.label
2162 2168

  
2163 2169
    # set as present without check_type
2164 2170
    resp = app.post(
......
2170 2176
    assert resp.pyquery.find('td.booking-actions button[disabled]')[0].text == 'Presence'
2171 2177
    booking.refresh_from_db()
2172 2178
    assert booking.user_was_present is True
2173
    assert booking.user_check_type is None
2179
    assert booking.user_check_type_slug is None
2180
    assert booking.user_check_type_label is None
2174 2181
    secondary_booking.refresh_from_db()
2175 2182
    assert secondary_booking.user_was_present is True
2176
    assert secondary_booking.user_check_type is None
2183
    assert secondary_booking.user_check_type_slug is None
2184
    assert secondary_booking.user_check_type_label is None
2177 2185
    event.refresh_from_db()
2178 2186
    assert event.checked is True
2179 2187

  
......
2191 2199
    # set as present with check_type
2192 2200
    resp = app.post(
2193 2201
        '/manage/agendas/%s/bookings/%s/presence' % (agenda.pk, booking.pk),
2194
        params={'csrfmiddlewaretoken': token, 'check_type': check_type_presence.pk},
2202
        params={'csrfmiddlewaretoken': token, 'check_type': check_type_presence.slug},
2195 2203
    ).follow()
2196 2204
    assert 'Bar reason' in resp
2197 2205
    booking.refresh_from_db()
2198 2206
    assert booking.user_was_present is True
2199
    assert booking.user_check_type == check_type_presence
2207
    assert booking.user_check_type_slug == check_type_presence.slug
2208
    assert booking.user_check_type_label == check_type_presence.label
2200 2209
    secondary_booking.refresh_from_db()
2201 2210
    assert secondary_booking.user_was_present is True
2202
    assert secondary_booking.user_check_type == check_type_presence
2211
    assert secondary_booking.user_check_type_slug == check_type_presence.slug
2212
    assert secondary_booking.user_check_type_label == check_type_presence.label
2203 2213

  
2204 2214
    # mark the event as checked
2205 2215
    event.checked = True
......
2257 2267
    # set as present
2258 2268
    resp = app.post(
2259 2269
        '/manage/agendas/%s/bookings/%s/presence' % (agenda.pk, booking.pk),
2260
        params={'csrfmiddlewaretoken': token, 'check_type': check_type_presence.pk},
2270
        params={'csrfmiddlewaretoken': token, 'check_type': check_type_presence.slug},
2261 2271
        extra_environ={'HTTP_X_REQUESTED_WITH': 'XMLHttpRequest'},
2262 2272
    )
2263 2273
    assert '<tr>' not in resp  # because this is a fragment
2264 2274
    assert resp.pyquery.find('td.booking-status')[0].text.strip() == 'Present\n  \n    (Bar reason)'
2265 2275
    assert len(resp.pyquery.find('td.booking-actions button[disabled]')) == 1
2266 2276
    assert resp.pyquery.find('td.booking-actions button[disabled]')[0].text == 'Presence'
2267
    assert '<option value="%s" selected>Bar reason</option>' % check_type_presence.pk in resp
2277
    assert '<option value="%s" selected>Bar reason</option>' % check_type_presence.slug in resp
2268 2278

  
2269 2279
    # set as absent
2270 2280
    resp = app.post(
2271 2281
        '/manage/agendas/%s/bookings/%s/absence' % (agenda.pk, booking.pk),
2272
        params={'csrfmiddlewaretoken': token, 'check_type': check_type_absence.pk},
2282
        params={'csrfmiddlewaretoken': token, 'check_type': check_type_absence.slug},
2273 2283
        extra_environ={'HTTP_X_REQUESTED_WITH': 'XMLHttpRequest'},
2274 2284
    )
2275 2285
    assert '<tr>' not in resp  # because this is a fragment
2276 2286
    assert resp.pyquery.find('td.booking-status')[0].text.strip() == 'Absent\n  \n    (Foo reason)'
2277 2287
    assert len(resp.pyquery.find('td.booking-actions button[disabled]')) == 1
2278 2288
    assert resp.pyquery.find('td.booking-actions button[disabled]')[0].text.startswith('Absence')
2279
    assert '<option value="%s" selected>Foo reason</option>' % check_type_absence.pk in resp
2289
    assert '<option value="%s" selected>Foo reason</option>' % check_type_absence.slug in resp
2280 2290

  
2281 2291

  
2282 2292
def test_event_check_all_bookings(app, admin_user):
......
2306 2316
    )
2307 2317
    booking1.refresh_from_db()
2308 2318
    assert booking1.user_was_present is False
2309
    assert booking1.user_check_type is None
2319
    assert booking1.user_check_type_slug is None
2320
    assert booking1.user_check_type_label is None
2310 2321
    event.refresh_from_db()
2311 2322
    assert event.checked is False
2312 2323

  
......
2332 2343
    )
2333 2344
    booking1.refresh_from_db()
2334 2345
    assert booking1.user_was_present is False
2335
    assert booking1.user_check_type is None
2346
    assert booking1.user_check_type_slug is None
2347
    assert booking1.user_check_type_label is None
2336 2348
    booking2.refresh_from_db()
2337 2349
    assert booking2.user_was_present is True
2338
    assert booking2.user_check_type is None
2350
    assert booking2.user_check_type_slug is None
2351
    assert booking2.user_check_type_label is None
2339 2352
    secondary_booking.refresh_from_db()
2340 2353
    assert secondary_booking.user_was_present is True
2341
    assert secondary_booking.user_check_type is None
2354
    assert secondary_booking.user_check_type_slug is None
2355
    assert secondary_booking.user_check_type_label is None
2342 2356
    event.refresh_from_db()
2343 2357
    assert event.checked is True
2344 2358

  
......
2348 2362
    assert 'Mark all bookings without status' in resp
2349 2363
    app.post(
2350 2364
        '/manage/agendas/%s/events/%s/absence' % (agenda.pk, event.pk),
2351
        params={'csrfmiddlewaretoken': token, 'check_type': check_type_absence.pk},
2365
        params={'csrfmiddlewaretoken': token, 'check_type': check_type_absence.slug},
2352 2366
    )
2353 2367
    booking1.refresh_from_db()
2354 2368
    assert booking1.user_was_present is False
2355
    assert booking1.user_check_type is None
2369
    assert booking1.user_check_type_slug is None
2370
    assert booking1.user_check_type_label is None
2356 2371
    booking2.refresh_from_db()
2357 2372
    assert booking2.user_was_present is True
2358
    assert booking2.user_check_type is None
2373
    assert booking2.user_check_type_slug is None
2374
    assert booking2.user_check_type_label is None
2359 2375
    booking3.refresh_from_db()
2360 2376
    assert booking3.user_was_present is False
2361
    assert booking3.user_check_type == check_type_absence
2377
    assert booking3.user_check_type_slug == check_type_absence.slug
2378
    assert booking3.user_check_type_label == check_type_absence.label
2362 2379

  
2363 2380
    booking4 = Booking.objects.create(event=event, user_first_name='User', user_last_name='52')
2364 2381
    resp = app.get('/manage/agendas/%s/events/%s/check' % (agenda.pk, event.pk))
2365 2382
    assert 'Mark all bookings without status' in resp
2366 2383
    app.post(
2367 2384
        '/manage/agendas/%s/events/%s/presence' % (agenda.pk, event.pk),
2368
        params={'csrfmiddlewaretoken': token, 'check_type': check_type_presence.pk},
2385
        params={'csrfmiddlewaretoken': token, 'check_type': check_type_presence.slug},
2369 2386
    )
2370 2387
    booking1.refresh_from_db()
2371 2388
    assert booking1.user_was_present is False
2372
    assert booking1.user_check_type is None
2389
    assert booking1.user_check_type_slug is None
2390
    assert booking1.user_check_type_label is None
2373 2391
    booking2.refresh_from_db()
2374 2392
    assert booking2.user_was_present is True
2375
    assert booking2.user_check_type is None
2393
    assert booking2.user_check_type_slug is None
2394
    assert booking2.user_check_type_label is None
2376 2395
    booking3.refresh_from_db()
2377 2396
    assert booking3.user_was_present is False
2378
    assert booking3.user_check_type == check_type_absence
2397
    assert booking3.user_check_type_slug == check_type_absence.slug
2398
    assert booking3.user_check_type_label == check_type_absence.label
2379 2399
    booking4.refresh_from_db()
2380 2400
    assert booking4.user_was_present is True
2381
    assert booking4.user_check_type == check_type_presence
2401
    assert booking4.user_check_type_slug == check_type_presence.slug
2402
    assert booking4.user_check_type_label == check_type_presence.label
2382 2403

  
2383 2404
    # now disable check update
2384 2405
    agenda.disable_check_update = True
......
2388 2409
    assert 'Mark all bookings without status' not in resp
2389 2410
    app.post(
2390 2411
        '/manage/agendas/%s/events/%s/absence' % (agenda.pk, event.pk),
2391
        params={'csrfmiddlewaretoken': token, 'check_type': check_type_absence.pk},
2412
        params={'csrfmiddlewaretoken': token, 'check_type': check_type_absence.slug},
2392 2413
        status=404,
2393 2414
    )
2394 2415
    resp = app.post(
......
2398 2419
    )
2399 2420
    app.post(
2400 2421
        '/manage/agendas/%s/events/%s/presence' % (agenda.pk, event.pk),
2401
        params={'csrfmiddlewaretoken': token, 'check_type': check_type_presence.pk},
2422
        params={'csrfmiddlewaretoken': token, 'check_type': check_type_presence.slug},
2402 2423
        status=404,
2403 2424
    )
2404 2425
    resp = app.post(
2405
-