From 4c7071f199dda3d286c203c605ad87e66edaefef Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Laur=C3=A9line=20Gu=C3=A9rin?= <zebuline@entrouvert.com>
Date: Fri, 10 Jun 2022 10:17:38 +0200
Subject: [PATCH 5/5] agendas: remove CheckType & CheckTypeGroup models
 (#66015)

---
 .../migrations/0131_remove_check_type.py      |  21 ++
 chrono/agendas/models.py                      | 105 --------
 chrono/api/views.py                           |  15 +-
 chrono/manager/forms.py                       |  26 --
 chrono/manager/static/css/style.scss          |  13 +-
 .../chrono/manager_check_type_form.html       |  36 ---
 .../chrono/manager_check_type_group_form.html |  31 ---
 .../chrono/manager_check_type_list.html       |  59 ----
 .../manager_events_agenda_settings.html       |  29 --
 .../templates/chrono/manager_home.html        |   1 -
 chrono/manager/urls.py                        |  36 ---
 chrono/manager/utils.py                       |   8 -
 chrono/manager/views.py                       | 207 +-------------
 tests/api/test_agenda.py                      |  27 +-
 tests/manager/test_check_type.py              | 254 ------------------
 tests/manager/test_event.py                   |   2 +-
 tests/manager/test_import_export.py           |  82 +-----
 tests/test_agendas.py                         |  20 --
 tests/test_import_export.py                   |  86 ------
 19 files changed, 34 insertions(+), 1024 deletions(-)
 create mode 100644 chrono/agendas/migrations/0131_remove_check_type.py
 delete mode 100644 chrono/manager/templates/chrono/manager_check_type_form.html
 delete mode 100644 chrono/manager/templates/chrono/manager_check_type_group_form.html
 delete mode 100644 chrono/manager/templates/chrono/manager_check_type_list.html
 delete mode 100644 tests/manager/test_check_type.py

diff --git a/chrono/agendas/migrations/0131_remove_check_type.py b/chrono/agendas/migrations/0131_remove_check_type.py
new file mode 100644
index 00000000..5e05e3fc
--- /dev/null
+++ b/chrono/agendas/migrations/0131_remove_check_type.py
@@ -0,0 +1,21 @@
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('agendas', '0130_remove_check_type'),
+    ]
+
+    operations = [
+        migrations.RemoveField(
+            model_name='agenda',
+            name='check_type_group',
+        ),
+        migrations.DeleteModel(
+            name='CheckType',
+        ),
+        migrations.DeleteModel(
+            name='CheckTypeGroup',
+        ),
+    ]
diff --git a/chrono/agendas/models.py b/chrono/agendas/models.py
index 3391d108..7fddcb4d 100644
--- a/chrono/agendas/models.py
+++ b/chrono/agendas/models.py
@@ -200,13 +200,6 @@ class Agenda(models.Model):
     category = models.ForeignKey(
         'Category', verbose_name=_('Category'), blank=True, null=True, on_delete=models.SET_NULL
     )
-    check_type_group = models.ForeignKey(
-        'CheckTypeGroup',
-        verbose_name=_('Check type group'),
-        blank=True,
-        null=True,
-        on_delete=models.SET_NULL,
-    )
     default_view = models.CharField(_('Default view'), max_length=20, choices=AGENDA_VIEWS)
     booking_form_url = models.CharField(
         _('Booking form URL'), max_length=200, blank=True, validators=[django_template_validator]
@@ -391,7 +384,6 @@ class Agenda(models.Model):
             agenda['events'] = [x.export_json() for x in self.event_set.filter(primary_event__isnull=True)]
             if hasattr(self, 'notifications_settings'):
                 agenda['notifications_settings'] = self.notifications_settings.export_json()
-            agenda['check_type_group'] = self.check_type_group.slug if self.check_type_group else None
             agenda['exceptions_desk'] = self.desk_set.get().export_json()
             agenda['minimal_booking_delay_in_working_days'] = self.minimal_booking_delay_in_working_days
             agenda['booking_user_block_template'] = self.booking_user_block_template
@@ -438,11 +430,6 @@ class Agenda(models.Model):
                 data['category'] = Category.objects.get(slug=data['category'])
             except Category.DoesNotExist:
                 del data['category']
-        if data.get('check_type_group'):
-            try:
-                data['check_type_group'] = CheckTypeGroup.objects.get(slug=data['check_type_group'])
-            except CheckTypeGroup.DoesNotExist:
-                raise AgendaImportError(_('Missing "%s" check type group') % data['check_type_group'])
         if data.get('events_type'):
             try:
                 data['events_type'] = EventsType.objects.get(slug=data['events_type'])
@@ -3051,98 +3038,6 @@ class AgendaReminderSettings(models.Model):
         return new_settings
 
 
-class CheckTypeGroup(models.Model):
-    slug = models.SlugField(_('Identifier'), max_length=160, unique=True)
-    label = models.CharField(_('Label'), max_length=150)
-
-    class Meta:
-        ordering = ['label']
-
-    def __str__(self):
-        return self.label
-
-    def save(self, *args, **kwargs):
-        if not self.slug:
-            self.slug = generate_slug(self)
-        super().save(*args, **kwargs)
-
-    @property
-    def base_slug(self):
-        return slugify(self.label)
-
-    @classmethod
-    def import_json(cls, data, overwrite=False):
-        check_types = data.pop('check_types', [])
-        data = clean_import_data(cls, data)
-        group, created = cls.objects.update_or_create(slug=data['slug'], defaults=data)
-
-        if overwrite:
-            CheckType.objects.filter(group=group).delete()
-
-        for check_type in check_types:
-            check_type['group'] = group
-            CheckType.import_json(check_type)
-
-        return created, group
-
-    def export_json(self):
-        return {
-            'label': self.label,
-            'slug': self.slug,
-            'check_types': [a.export_json() for a in self.check_types.all()],
-        }
-
-
-class CheckTypeManager(models.Manager):
-    def absences(self):
-        return self.filter(kind='absence', disabled=False)
-
-    def presences(self):
-        return self.filter(kind='presence', disabled=False)
-
-
-class CheckType(models.Model):
-    group = models.ForeignKey(CheckTypeGroup, on_delete=models.CASCADE, related_name='check_types')
-    slug = models.SlugField(_('Identifier'), max_length=160)
-    label = models.CharField(_('Label'), max_length=150)
-    kind = models.CharField(
-        _('Kind'),
-        max_length=8,
-        choices=[('absence', _('Absence')), ('presence', _('Presence'))],
-        default='absence',
-    )
-    disabled = models.BooleanField(_('Disabled'), default=False)
-    objects = CheckTypeManager()
-
-    class Meta:
-        ordering = ['label']
-        unique_together = ['group', 'slug']
-
-    def __str__(self):
-        return self.label
-
-    def save(self, *args, **kwargs):
-        if not self.slug:
-            self.slug = generate_slug(self, group=self.group)
-        super().save(*args, **kwargs)
-
-    @property
-    def base_slug(self):
-        return slugify(self.label)
-
-    @classmethod
-    def import_json(cls, data):
-        data = clean_import_data(cls, data)
-        cls.objects.update_or_create(slug=data['slug'], group=data['group'], defaults=data)
-
-    def export_json(self):
-        return {
-            'label': self.label,
-            'slug': self.slug,
-            'kind': self.kind,
-        }
-
-
 class Subscription(models.Model):
     agenda = models.ForeignKey(Agenda, on_delete=models.CASCADE, related_name='subscriptions')
     user_external_id = models.CharField(max_length=250)
diff --git a/chrono/api/views.py b/chrono/api/views.py
index 1657fa3d..35213f6d 100644
--- a/chrono/api/views.py
+++ b/chrono/api/views.py
@@ -380,17 +380,6 @@ def get_agenda_detail(request, agenda, check_events=False):
         }
         if check_events:
             agenda_detail['opened_events_available'] = bool(agenda.get_open_events().filter(full=False))
-        if agenda.check_type_group:
-            agenda_detail['absence_reasons'] = [
-                {'id': r.slug, 'slug': r.slug, 'text': r.label, 'label': r.label}
-                for r in agenda.check_type_group.check_types.all()
-                if r.kind == 'absence'
-            ]
-            agenda_detail['presence_reasons'] = [
-                {'id': r.slug, 'slug': r.slug, 'text': r.label, 'label': r.label}
-                for r in agenda.check_type_group.check_types.all()
-                if r.kind == 'presence'
-            ]
     elif agenda.accept_meetings():
         agenda_detail['api'] = {
             'meetings_url': request.build_absolute_uri(
@@ -742,8 +731,8 @@ class Agendas(APIView):
     def get(self, request, format=None):
         agendas_queryset = (
             Agenda.objects.all()
-            .select_related('check_type_group', 'category', 'edit_role', 'view_role', 'events_type')
-            .prefetch_related('resources', 'check_type_group__check_types')
+            .select_related('category', 'edit_role', 'view_role', 'events_type')
+            .prefetch_related('resources')
             .order_by('label')
         )
 
diff --git a/chrono/manager/forms.py b/chrono/manager/forms.py
index 3755e54e..a1da05b7 100644
--- a/chrono/manager/forms.py
+++ b/chrono/manager/forms.py
@@ -44,8 +44,6 @@ from chrono.agendas.models import (
     AgendaNotificationsSettings,
     AgendaReminderSettings,
     Booking,
-    CheckType,
-    CheckTypeGroup,
     Desk,
     Event,
     EventsType,
@@ -70,20 +68,6 @@ from . import widgets
 from .widgets import SplitDateTimeField, WeekdaysWidget
 
 
-class CheckTypeForm(forms.ModelForm):
-    class Meta:
-        model = CheckType
-        fields = ['label', 'slug', 'disabled']
-
-    def clean_slug(self):
-        slug = self.cleaned_data['slug']
-
-        if self.instance.group.check_types.filter(slug=slug).exclude(pk=self.instance.pk).exists():
-            raise ValidationError(_('Another check type exists with the same identifier.'))
-
-        return slug
-
-
 class AgendaAddForm(forms.ModelForm):
     edit_role = forms.ModelChoiceField(
         label=_('Edit Role'), required=False, queryset=Group.objects.all().order_by('name')
@@ -1288,7 +1272,6 @@ class AgendaBookingCheckSettingsForm(forms.ModelForm):
     class Meta:
         model = Agenda
         fields = [
-            'check_type_group',
             'booking_check_filters',
             'booking_user_block_template',
             'mark_event_checked_auto',
@@ -1296,14 +1279,6 @@ class AgendaBookingCheckSettingsForm(forms.ModelForm):
         ]
         widgets = {'booking_user_block_template': forms.Textarea(attrs={'rows': 3})}
 
-    def __init__(self, *args, **kwargs):
-        super().__init__(*args, **kwargs)
-        if not CheckTypeGroup.objects.exists():
-            del self.fields['check_type_group']
-        elif Booking.objects.filter(event__agenda=self.instance, user_check_type_slug__isnull=False).exists():
-            # not possible to update check_type_group if bookings with non null check_type exist
-            del self.fields['check_type_group']
-
 
 class AgendaNotificationsForm(forms.ModelForm):
     class Meta:
@@ -1402,7 +1377,6 @@ class AgendasExportForm(forms.Form):
         label=_('Unavailability calendars'), required=False, initial=True
     )
     categories = forms.BooleanField(label=_('Categories'), required=False, initial=True)
-    check_type_groups = forms.BooleanField(label=_('Check type groups'), required=False, initial=True)
     events_types = forms.BooleanField(label=_('Events types'), required=False, initial=True)
 
 
diff --git a/chrono/manager/static/css/style.scss b/chrono/manager/static/css/style.scss
index 0624a44c..c3a34ebb 100644
--- a/chrono/manager/static/css/style.scss
+++ b/chrono/manager/static/css/style.scss
@@ -74,9 +74,7 @@ h2 span.identifier {
 	margin-top: 0;
 }
 
-.timeperiods .timeperiod a.add::before,
-.check-type-group h3 a.delete::before,
-.check-type-group a.add::before {
+.timeperiods .timeperiod a.add::before {
 	content: "\f055"; /* plus-circle */
 	font-family: FontAwesome;
 	padding-right: 1ex;
@@ -90,15 +88,6 @@ a.timeperiod-exception-all {
 	content: "\f0ad"; /* wrench */
 }
 
-.check-type-group h3 a.delete {
-	width: 1em;
-	overflow: hidden;
-	&::before {
-		content: "\f057"; /* remove-sign */
-		padding-right: 3em;
-	}
-}
-
 .dayview h2 a,
 .monthview h2 a {
 	padding: 0 1ex;
diff --git a/chrono/manager/templates/chrono/manager_check_type_form.html b/chrono/manager/templates/chrono/manager_check_type_form.html
deleted file mode 100644
index 09027850..00000000
--- a/chrono/manager/templates/chrono/manager_check_type_form.html
+++ /dev/null
@@ -1,36 +0,0 @@
-{% extends "chrono/manager_check_type_list.html" %}
-{% load i18n %}
-
-{% block breadcrumb %}
-{{ block.super }}
-{% if form.instance.pk %}
-<a href="{% url 'chrono-manager-check-type-edit' form.instance.group_id form.instance.pk %}">{{ form.instance }}</a>
-{% else %}
-<a href="{% url 'chrono-manager-check-type-add' form.instance.group_id %}">{% trans "New check type" %}</a>
-{% endif %}
-{% endblock %}
-
-{% block appbar %}
-{% if form.instance.pk %}
-<h2>{{ form.instance.group }} - {% trans "Edit check type" %}</h2>
-{% else %}
-<h2>{{ form.instance.group }} - {% trans "New check type" %}</h2>
-{% endif %}
-{% endblock %}
-
-{% block content %}
-
-<form method="post" enctype="multipart/form-data">
-  {% csrf_token %}
-  {% if is_used %}
-  <p>
-  {% trans "This check type is set on some existing bookings, modify it with caution." %}
-  </p>
-  {% endif %}
-  {{ form.as_p }}
-  <div class="buttons">
-    <button class="submit-button">{% trans "Save" %}</button>
-    <a class="cancel" href="{% url 'chrono-manager-check-type-list' %}">{% trans 'Cancel' %}</a>
-  </div>
-</form>
-{% endblock %}
diff --git a/chrono/manager/templates/chrono/manager_check_type_group_form.html b/chrono/manager/templates/chrono/manager_check_type_group_form.html
deleted file mode 100644
index e7270e8b..00000000
--- a/chrono/manager/templates/chrono/manager_check_type_group_form.html
+++ /dev/null
@@ -1,31 +0,0 @@
-{% extends "chrono/manager_check_type_list.html" %}
-{% load i18n %}
-
-{% block breadcrumb %}
-{{ block.super }}
-{% if object.pk %}
-<a href="{% url 'chrono-manager-check-type-group-edit' object.pk %}">{{ object }}</a>
-{% else %}
-<a href="{% url 'chrono-manager-check-type-group-add' %}">{% trans "New check type group" %}</a>
-{% endif %}
-{% endblock %}
-
-{% block appbar %}
-{% if object.pk %}
-<h2>{% trans "Edit check type group" %}</h2>
-{% else %}
-<h2>{% trans "New check type group" %}</h2>
-{% endif %}
-{% endblock %}
-
-{% block content %}
-
-<form method="post" enctype="multipart/form-data">
-  {% csrf_token %}
-  {{ form.as_p }}
-  <div class="buttons">
-    <button class="submit-button">{% trans "Save" %}</button>
-    <a class="cancel" href="{% url 'chrono-manager-check-type-list' %}">{% trans 'Cancel' %}</a>
-  </div>
-</form>
-{% endblock %}
diff --git a/chrono/manager/templates/chrono/manager_check_type_list.html b/chrono/manager/templates/chrono/manager_check_type_list.html
deleted file mode 100644
index 09893c8e..00000000
--- a/chrono/manager/templates/chrono/manager_check_type_list.html
+++ /dev/null
@@ -1,59 +0,0 @@
-{% extends "chrono/manager_base.html" %}
-{% load i18n %}
-
-{% block breadcrumb %}
-{{ block.super }}
-<a href="{% url 'chrono-manager-check-type-list' %}">{% trans "Check types" %}</a>
-{% endblock %}
-
-{% block appbar %}
-<h2>{% trans 'Check types' %}</h2>
-<span class="actions">
-<a rel="popup" href="{% url 'chrono-manager-check-type-group-add' %}">{% trans 'New group' %}</a>
-</span>
-{% endblock %}
-
-{% block content %}
-<div class="pk-information">
-<p>{% trans "Define here check types used in events agendas to check bookings." %}</p>
-</div>
-{% for object in object_list %}
-<div class="section check-type-group">
-    <h3>
-    <a rel="popup" href="{% url 'chrono-manager-check-type-group-edit' object.pk %}">{{ object }}</a>
-    <span>
-    <a class="button" href="{% url 'chrono-manager-check-type-group-export' object.pk %}">{% trans "Export"%}</a>
-    <a class="button" rel="popup" href="{% url 'chrono-manager-check-type-group-delete' object.pk %}">{% trans "Delete"%}</a>
-    </span>
-    </h3>
-  <div>
-  <ul class="objects-list single-links">
-    {% for check_type in object.check_types.all %}
-    {% if check_type.kind == 'absence' %}
-    <li>
-        <a rel="popup" href="{% url 'chrono-manager-check-type-edit' object.pk check_type.pk %}">{% trans "Absence" %} - {{ check_type }}{% if check_type.disabled %}<span class="extra-info"> ({% trans "disabled" %})</span>{% endif %}</a>
-        <a class="delete" rel="popup" href="{% url 'chrono-manager-check-type-delete' object.pk check_type.pk %}">{% trans "delete"%}</a>
-    </li>
-    {% endif %}
-    {% endfor %}
-    {% for check_type in object.check_types.all %}
-    {% if check_type.kind == 'presence' %}
-    <li>
-        <a rel="popup" href="{% url 'chrono-manager-check-type-edit' object.pk check_type.pk %}">{% trans "Presence" %} - {{ check_type }}{% if check_type.disabled %}<span class="extra-info"> ({% trans "disabled" %})</span>{% endif %}</a>
-        <a class="delete" rel="popup" href="{% url 'chrono-manager-check-type-delete' object.pk check_type.pk %}">{% trans "delete"%}</a>
-    </li>
-    {% endif %}
-    {% endfor %}
-    <li><a class="add" rel="popup" href="{% url 'chrono-manager-check-type-add' object.pk %}">{% trans "Add a check type" %}</a></li>
-  </ul>
-  </div>
-</div>
-{% empty %}
-<div class="big-msg-info">
-  {% blocktrans %}
-  This site doesn't have any check type group yet. Click on the "New group" button in the top
-  right of the page to add a first one.
-  {% endblocktrans %}
-</div>
-{% endfor %}
-{% endblock %}
diff --git a/chrono/manager/templates/chrono/manager_events_agenda_settings.html b/chrono/manager/templates/chrono/manager_events_agenda_settings.html
index e7a02d6d..9885a50f 100644
--- a/chrono/manager/templates/chrono/manager_events_agenda_settings.html
+++ b/chrono/manager/templates/chrono/manager_events_agenda_settings.html
@@ -36,35 +36,6 @@
 </h3>
 <div>
     <ul>
-    {% if has_check_types %}
-        {% if agenda.check_type_group %}
-        <li>{% trans "Check type group:" %} {{ agenda.check_type_group }}
-            <ul>
-                <li>{% trans "Absences:" %}
-                    <ul>
-                      {% for check_type in agenda.check_type_group.check_types.absences %}
-                      <li>{{ check_type }}</li>
-                      {% empty %}
-                      <li>({% trans "No absence check type defined" %})</li>
-                      {% endfor %}
-                    </ul>
-                </li>
-                <li>{% trans "Presences:" %}
-                    <ul>
-                      {% for check_type in agenda.check_type_group.check_types.presences %}
-                      <li>{{ check_type }}</li>
-                      {% empty %}
-                      <li>({% trans "No presence check type defined" %})</li>
-                      {% endfor %}
-                    </ul>
-                </li>
-            </ul>
-        </li>
-        {% else %}
-        <li>{% trans "No check types configured for this agenda." %}</li>
-        {% endif %}
-    {% endif %}
-
     {% with agenda.get_booking_check_filters as check_filters %}
         {% if check_filters %}
         <li>{% trans "Filters:" %}
diff --git a/chrono/manager/templates/chrono/manager_home.html b/chrono/manager/templates/chrono/manager_home.html
index 78ea9796..77fe50af 100644
--- a/chrono/manager/templates/chrono/manager_home.html
+++ b/chrono/manager/templates/chrono/manager_home.html
@@ -11,7 +11,6 @@
     <li><a rel="popup" href="{% url 'chrono-manager-agendas-import' %}">{% trans 'Import' %}</a></li>
     <li><a rel="popup" href="{% url 'chrono-manager-agendas-export' %}" data-autoclose-dialog="true">{% trans 'Export' %}</a></li>
     <li><a href="{% url 'chrono-manager-events-type-list' %}">{% trans 'Events types' %}</a></li>
-    <li><a href="{% url 'chrono-manager-check-type-list' %}">{% trans 'Check types' %}</a></li>
     {% endif %}
     {% if has_access_to_unavailability_calendars %}
     <li><a href="{% url 'chrono-manager-unavailability-calendar-list' %}">{% trans 'Unavailability calendars' %}</a></li>
diff --git a/chrono/manager/urls.py b/chrono/manager/urls.py
index 24dff30e..d41bacfe 100644
--- a/chrono/manager/urls.py
+++ b/chrono/manager/urls.py
@@ -84,42 +84,6 @@ urlpatterns = [
     url(r'^category/add/$', views.category_add, name='chrono-manager-category-add'),
     url(r'^category/(?P<pk>\d+)/edit/$', views.category_edit, name='chrono-manager-category-edit'),
     url(r'^category/(?P<pk>\d+)/delete/$', views.category_delete, name='chrono-manager-category-delete'),
-    url(r'^check-types/$', views.check_type_list, name='chrono-manager-check-type-list'),
-    url(
-        r'^check-type/group/add/$',
-        views.check_type_group_add,
-        name='chrono-manager-check-type-group-add',
-    ),
-    url(
-        r'^check-type/group/(?P<pk>\d+)/edit/$',
-        views.check_type_group_edit,
-        name='chrono-manager-check-type-group-edit',
-    ),
-    url(
-        r'^check-type/group/(?P<pk>\d+)/delete/$',
-        views.check_type_group_delete,
-        name='chrono-manager-check-type-group-delete',
-    ),
-    url(
-        r'^check-type/group/(?P<pk>\d+)/export/$',
-        views.check_type_group_export,
-        name='chrono-manager-check-type-group-export',
-    ),
-    url(
-        r'^check-type/group/(?P<group_pk>\d+)/add/$',
-        views.check_type_add,
-        name='chrono-manager-check-type-add',
-    ),
-    url(
-        r'^check-type/group/(?P<group_pk>\d+)/(?P<pk>\d+)/edit/$',
-        views.check_type_edit,
-        name='chrono-manager-check-type-edit',
-    ),
-    url(
-        r'^check-type/group/(?P<group_pk>\d+)/(?P<pk>\d+)/delete/$',
-        views.check_type_delete,
-        name='chrono-manager-check-type-delete',
-    ),
     url(r'^events-types/$', views.events_type_list, name='chrono-manager-events-type-list'),
     url(r'^events-type/add/$', views.events_type_add, name='chrono-manager-events-type-add'),
     url(r'^events-type/(?P<pk>\d+)/edit/$', views.events_type_edit, name='chrono-manager-events-type-edit'),
diff --git a/chrono/manager/utils.py b/chrono/manager/utils.py
index 0e2952f2..68c065a2 100644
--- a/chrono/manager/utils.py
+++ b/chrono/manager/utils.py
@@ -25,7 +25,6 @@ from chrono.agendas.models import (
     Agenda,
     AgendaImportError,
     Category,
-    CheckTypeGroup,
     EventsType,
     Resource,
     UnavailabilityCalendar,
@@ -35,7 +34,6 @@ from chrono.agendas.models import (
 def export_site(
     agendas=True,
     unavailability_calendars=True,
-    check_type_groups=True,
     events_types=True,
     resources=True,
     categories=True,
@@ -48,8 +46,6 @@ def export_site(
         data['resources'] = [x.export_json() for x in Resource.objects.all()]
     if events_types:
         data['events_types'] = [x.export_json() for x in EventsType.objects.all()]
-    if check_type_groups:
-        data['check_type_groups'] = [x.export_json() for x in CheckTypeGroup.objects.all()]
     if unavailability_calendars:
         data['unavailability_calendars'] = [x.export_json() for x in UnavailabilityCalendar.objects.all()]
     if agendas:
@@ -64,7 +60,6 @@ def import_site(data, if_empty=False, clean=False, overwrite=False):
     if if_empty and (
         Agenda.objects.exists()
         or UnavailabilityCalendar.objects.exists()
-        or CheckTypeGroup.objects.exists()
         or EventsType.objects.exists()
         or Resource.objects.exists()
         or Category.objects.exists()
@@ -74,7 +69,6 @@ def import_site(data, if_empty=False, clean=False, overwrite=False):
     if clean:
         Agenda.objects.all().delete()
         UnavailabilityCalendar.objects.all().delete()
-        CheckTypeGroup.objects.all().delete()
         EventsType.objects.all().delete()
         Resource.objects.all().delete()
         Category.objects.all().delete()
@@ -84,7 +78,6 @@ def import_site(data, if_empty=False, clean=False, overwrite=False):
         for key in [
             'agendas',
             'unavailability_calendars',
-            'check_type_groups',
             'events_types',
             'resources',
             'categories',
@@ -108,7 +101,6 @@ def import_site(data, if_empty=False, clean=False, overwrite=False):
             (Category, 'categories'),
             (Resource, 'resources'),
             (EventsType, 'events_types'),
-            (CheckTypeGroup, 'check_type_groups'),
             (UnavailabilityCalendar, 'unavailability_calendars'),
             (Agenda, 'agendas'),
         ):
diff --git a/chrono/manager/views.py b/chrono/manager/views.py
index 02f7b315..1ac879d9 100644
--- a/chrono/manager/views.py
+++ b/chrono/manager/views.py
@@ -67,8 +67,6 @@ from chrono.agendas.models import (
     Booking,
     BookingColor,
     Category,
-    CheckType,
-    CheckTypeGroup,
     Desk,
     Event,
     EventCancellationReport,
@@ -105,7 +103,6 @@ from .forms import (
     BookingCheckAbsenceForm,
     BookingCheckFilterSet,
     BookingCheckPresenceForm,
-    CheckTypeForm,
     CustomFieldFormSet,
     DeskExceptionsImportForm,
     DeskForm,
@@ -655,180 +652,6 @@ class CategoryDeleteView(DeleteView):
 category_delete = CategoryDeleteView.as_view()
 
 
-class CheckTypeListView(ListView):
-    template_name = 'chrono/manager_check_type_list.html'
-    model = CheckTypeGroup
-
-    def dispatch(self, request, *args, **kwargs):
-        if not request.user.is_staff:
-            raise PermissionDenied()
-        return super().dispatch(request, *args, **kwargs)
-
-    def get_queryset(self):
-        return CheckTypeGroup.objects.prefetch_related('check_types')
-
-
-check_type_list = CheckTypeListView.as_view()
-
-
-class CheckTypeGroupAddView(CreateView):
-    template_name = 'chrono/manager_check_type_group_form.html'
-    model = CheckTypeGroup
-    fields = ['label']
-
-    def dispatch(self, request, *args, **kwargs):
-        if not request.user.is_staff:
-            raise PermissionDenied()
-        return super().dispatch(request, *args, **kwargs)
-
-    def get_success_url(self):
-        return reverse('chrono-manager-check-type-list')
-
-
-check_type_group_add = CheckTypeGroupAddView.as_view()
-
-
-class CheckTypeGroupEditView(UpdateView):
-    template_name = 'chrono/manager_check_type_group_form.html'
-    model = CheckTypeGroup
-    fields = ['label', 'slug']
-
-    def dispatch(self, request, *args, **kwargs):
-        if not request.user.is_staff:
-            raise PermissionDenied()
-        return super().dispatch(request, *args, **kwargs)
-
-    def get_success_url(self):
-        return reverse('chrono-manager-check-type-list')
-
-
-check_type_group_edit = CheckTypeGroupEditView.as_view()
-
-
-class CheckTypeGroupDeleteView(DeleteView):
-    template_name = 'chrono/manager_confirm_delete.html'
-    model = CheckTypeGroup
-
-    def dispatch(self, request, *args, **kwargs):
-        if not request.user.is_staff:
-            raise PermissionDenied()
-        return super().dispatch(request, *args, **kwargs)
-
-    def get_success_url(self):
-        return reverse('chrono-manager-check-type-list')
-
-
-check_type_group_delete = CheckTypeGroupDeleteView.as_view()
-
-
-class CheckTypeGroupExport(DetailView):
-    model = CheckTypeGroup
-
-    def dispatch(self, request, *args, **kwargs):
-        if not request.user.is_staff:
-            raise PermissionDenied()
-        return super().dispatch(request, *args, **kwargs)
-
-    def get(self, request, *args, **kwargs):
-        response = HttpResponse(content_type='application/json')
-        today = datetime.date.today()
-        attachment = 'attachment; filename="export_check_type_group_{}_{}.json"'.format(
-            self.get_object().slug, today.strftime('%Y%m%d')
-        )
-        response['Content-Disposition'] = attachment
-        json.dump({'check_type_groups': [self.get_object().export_json()]}, response, indent=2)
-        return response
-
-
-check_type_group_export = CheckTypeGroupExport.as_view()
-
-
-class CheckTypeAddView(CreateView):
-    template_name = 'chrono/manager_check_type_form.html'
-    model = CheckType
-    fields = ['label', 'kind']
-
-    def dispatch(self, request, *args, **kwargs):
-        self.group_pk = kwargs.pop('group_pk')
-        if not request.user.is_staff:
-            raise PermissionDenied()
-        return super().dispatch(request, *args, **kwargs)
-
-    def get_form_kwargs(self):
-        kwargs = super().get_form_kwargs()
-        if not kwargs.get('instance'):
-            kwargs['instance'] = self.model()
-        kwargs['instance'].group_id = self.group_pk
-        return kwargs
-
-    def get_success_url(self):
-        return reverse('chrono-manager-check-type-list')
-
-
-check_type_add = CheckTypeAddView.as_view()
-
-
-class CheckTypeEditView(UpdateView):
-    template_name = 'chrono/manager_check_type_form.html'
-    model = CheckType
-    form_class = CheckTypeForm
-
-    def dispatch(self, request, *args, **kwargs):
-        self.group_pk = kwargs.pop('group_pk')
-        if not request.user.is_staff:
-            raise PermissionDenied()
-        return super().dispatch(request, *args, **kwargs)
-
-    def get_queryset(self):
-        return CheckType.objects.filter(group=self.group_pk)
-
-    def get_context_data(self, **kwargs):
-        context = super().get_context_data(**kwargs)
-        context['is_used'] = Booking.objects.filter(user_check_type_slug=self.get_object().slug).exists()
-        return context
-
-    def get_success_url(self):
-        return reverse('chrono-manager-check-type-list')
-
-
-check_type_edit = CheckTypeEditView.as_view()
-
-
-class CheckTypeDeleteView(DeleteView):
-    template_name = 'chrono/manager_confirm_delete.html'
-    model = CheckType
-
-    def dispatch(self, request, *args, **kwargs):
-        self.group_pk = kwargs.pop('group_pk')
-        if not request.user.is_staff:
-            raise PermissionDenied()
-        return super().dispatch(request, *args, **kwargs)
-
-    def get_queryset(self):
-        return CheckType.objects.filter(group=self.group_pk)
-
-    def get_context_data(self, **kwargs):
-        context = super().get_context_data(**kwargs)
-        context['cannot_delete'] = Booking.objects.filter(
-            user_check_type_slug=self.get_object().slug
-        ).exists()
-        context['cannot_delete_msg'] = _(
-            'Can not delete this check type: it is set on some existing bookings.'
-        )
-        return context
-
-    def delete(self, request, *args, **kwargs):
-        if Booking.objects.filter(user_check_type_slug=self.get_object().slug).exists():
-            raise Http404
-        return super().delete(request, *args, **kwargs)
-
-    def get_success_url(self):
-        return reverse('chrono-manager-check-type-list')
-
-
-check_type_delete = CheckTypeDeleteView.as_view()
-
-
 class EventsTypeListView(ListView):
     template_name = 'chrono/manager_events_type_list.html'
     model = EventsType
@@ -1002,20 +825,6 @@ class AgendasImportView(FormView):
                     x,
                 ),
             },
-            'check_type_groups': {
-                'create_noop': _('No check type group created.'),
-                'create': lambda x: ungettext(
-                    'A check type group has been created.',
-                    '%(count)d check type groups have been created.',
-                    x,
-                ),
-                'update_noop': _('No check type group updated.'),
-                'update': lambda x: ungettext(
-                    'A check type group has been updated.',
-                    '%(count)d check type groups have been updated.',
-                    x,
-                ),
-            },
             'events_types': {
                 'create_noop': _('No events type created.'),
                 'create': lambda x: ungettext(
@@ -1078,17 +887,16 @@ class AgendasImportView(FormView):
 
                 obj_results['messages'] = "%s %s" % (message1, message2)
 
-        a_count, uc_count, arg_count = (
+        a_count, uc_count = (
             len(results['agendas']['all']),
             len(results['unavailability_calendars']['all']),
-            len(results['check_type_groups']['all']),
         )
-        if (a_count, uc_count, arg_count) == (1, 0, 0):
+        if (a_count, uc_count) == (1, 0):
             # only one agenda imported, redirect to settings page
             return HttpResponseRedirect(
                 reverse('chrono-manager-agenda-settings', kwargs={'pk': results['agendas']['all'][0].pk})
             )
-        if (a_count, uc_count, arg_count) == (0, 1, 0):
+        if (a_count, uc_count) == (0, 1):
             # only one unavailability calendar imported, redirect to settings page
             return HttpResponseRedirect(
                 reverse(
@@ -1096,16 +904,12 @@ class AgendasImportView(FormView):
                     kwargs={'pk': results['unavailability_calendars']['all'][0].pk},
                 )
             )
-        if (a_count, uc_count, arg_count) == (0, 0, 1):
-            # only one check type group imported, redirect to check type page
-            return HttpResponseRedirect(reverse('chrono-manager-check-type-list'))
 
         if global_noop:
             messages.info(self.request, _('No data found.'))
         else:
             messages.info(self.request, results['agendas']['messages'])
             messages.info(self.request, results['unavailability_calendars']['messages'])
-            messages.info(self.request, results['check_type_groups']['messages'])
             messages.info(self.request, results['events_types']['messages'])
             messages.info(self.request, results['resources']['messages'])
             messages.info(self.request, results['categories']['messages'])
@@ -1828,7 +1632,7 @@ class AgendaSettings(ManagedAgendaMixin, DetailView):
 
     def set_agenda(self, **kwargs):
         self.agenda = get_object_or_404(
-            Agenda.objects.select_related('edit_role', 'view_role', 'check_type_group'),
+            Agenda.objects.select_related('edit_role', 'view_role'),
             pk=kwargs.get('pk'),
         )
 
@@ -1855,7 +1659,6 @@ class AgendaSettings(ManagedAgendaMixin, DetailView):
                 else False
             )
         if self.agenda.kind == 'events':
-            context['has_check_types'] = CheckTypeGroup.objects.exists()
             context['has_recurring_events'] = self.agenda.event_set.filter(
                 recurrence_days__isnull=False
             ).exists()
@@ -2299,7 +2102,7 @@ class EventCheckView(ViewableAgendaMixin, DetailView):
 
     def set_agenda(self, **kwargs):
         self.agenda = get_object_or_404(
-            Agenda.objects.prefetch_related('check_type_group__check_types'),
+            Agenda,
             pk=kwargs.get('pk'),
             kind='events',
         )
diff --git a/tests/api/test_agenda.py b/tests/api/test_agenda.py
index 0b0f2eaf..5158586d 100644
--- a/tests/api/test_agenda.py
+++ b/tests/api/test_agenda.py
@@ -10,8 +10,6 @@ from chrono.agendas.models import (
     Agenda,
     Booking,
     Category,
-    CheckType,
-    CheckTypeGroup,
     Desk,
     Event,
     EventsType,
@@ -27,23 +25,18 @@ def test_agendas_api(app):
     view_group = Group.objects.create(name='View')
     category_a = Category.objects.create(label='Category A')
     category_b = Category.objects.create(label='Category B')
-    group = CheckTypeGroup.objects.create(label='Foo')
-    reason = CheckType.objects.create(group=group, label='Foo bar')
-    reason2 = CheckType.objects.create(group=group, label='Foo bar baz')
-    reason3 = CheckType.objects.create(group=group, label='Foo bar baz presence', kind='presence')
     events_type = EventsType.objects.create(label='Type A')
     events_type2 = EventsType.objects.create(label='Type B')
     event_agenda = Agenda.objects.create(
         label='Foo bar',
         category=category_a,
-        check_type_group=group,
         events_type=events_type,
         edit_role=edit_group,
     )
     Desk.objects.create(agenda=event_agenda, slug='_exceptions_holder')
     event_agenda2 = Agenda.objects.create(label='Foo bar 2', category=category_a, events_type=events_type2)
     Desk.objects.create(agenda=event_agenda2, slug='_exceptions_holder')
-    event_agenda3 = Agenda.objects.create(label='Foo bar 3', check_type_group=group)
+    event_agenda3 = Agenda.objects.create(label='Foo bar 3')
     Desk.objects.create(agenda=event_agenda3, slug='_exceptions_holder')
     meetings_agenda1 = Agenda.objects.create(
         label='Foo bar Meeting', kind='meetings', category=category_b, view_role=view_group
@@ -78,13 +71,6 @@ def test_agendas_api(app):
                 'category': 'category-a',
                 'category_label': 'Category A',
                 'events_type': 'type-a',
-                'absence_reasons': [
-                    {'id': reason.slug, 'slug': reason.slug, 'text': reason.label, 'label': reason.label},
-                    {'id': reason2.slug, 'slug': reason2.slug, 'text': reason2.label, 'label': reason2.label},
-                ],
-                'presence_reasons': [
-                    {'id': reason3.slug, 'slug': reason3.slug, 'text': reason3.label, 'label': reason3.label},
-                ],
                 'api': {
                     'datetimes_url': 'http://testserver/api/agenda/foo-bar/datetimes/',
                     'fillslots_url': 'http://testserver/api/agenda/foo-bar/fillslots/',
@@ -123,13 +109,6 @@ def test_agendas_api(app):
                 'category': None,
                 'category_label': None,
                 'events_type': None,
-                'absence_reasons': [
-                    {'id': reason.slug, 'slug': reason.slug, 'text': reason.label, 'label': reason.label},
-                    {'id': reason2.slug, 'slug': reason2.slug, 'text': reason2.label, 'label': reason2.label},
-                ],
-                'presence_reasons': [
-                    {'id': reason3.slug, 'slug': reason3.slug, 'text': reason3.label, 'label': reason3.label},
-                ],
                 'api': {
                     'datetimes_url': 'http://testserver/api/agenda/foo-bar-3/datetimes/',
                     'fillslots_url': 'http://testserver/api/agenda/foo-bar-3/fillslots/',
@@ -209,7 +188,7 @@ def test_agendas_api(app):
 
     with CaptureQueriesContext(connection) as ctx:
         resp = app.get('/api/agenda/')
-        assert len(ctx.captured_queries) == 4
+        assert len(ctx.captured_queries) == 3
     with CaptureQueriesContext(connection) as ctx:
         resp = app.get('/api/agenda/', params={'q': 'MEET'})
         assert len(ctx.captured_queries) == 2
@@ -328,7 +307,7 @@ def test_agendas_api(app):
 
     with CaptureQueriesContext(connection) as ctx:
         resp = app.get('/api/agenda/', params={'with_open_events': '1'})
-        assert len(ctx.captured_queries) == 4
+        assert len(ctx.captured_queries) == 3
 
 
 def test_agenda_detail_api(app):
diff --git a/tests/manager/test_check_type.py b/tests/manager/test_check_type.py
deleted file mode 100644
index 08923471..00000000
--- a/tests/manager/test_check_type.py
+++ /dev/null
@@ -1,254 +0,0 @@
-import pytest
-from django.utils.timezone import now
-
-from chrono.agendas.models import Agenda, Booking, CheckType, CheckTypeGroup, Desk, Event
-from tests.utils import login
-
-pytestmark = pytest.mark.django_db
-
-
-@pytest.fixture
-def agenda_with_restrictions(manager_user):
-    agenda = Agenda(label='Foo Bar')
-    agenda.view_role = manager_user.groups.all()[0]
-    agenda.save()
-    return agenda
-
-
-def test_list_types_as_manager(app, manager_user, agenda_with_restrictions):
-    app = login(app, username='manager', password='manager')
-    app.get('/manage/check-types/', status=403)
-
-    resp = app.get('/manage/')
-    assert 'Check types' not in resp.text
-
-
-def test_add_group(app, admin_user):
-    app = login(app)
-    resp = app.get('/manage/')
-    resp = resp.click('Check types')
-    resp = resp.click('New group')
-    resp.form['label'] = 'Foo bar'
-    resp = resp.form.submit()
-    group = CheckTypeGroup.objects.latest('pk')
-    assert resp.location.endswith('/manage/check-types/')
-    assert group.label == 'Foo bar'
-    assert group.slug == 'foo-bar'
-
-
-def test_add_group_as_manager(app, manager_user, agenda_with_restrictions):
-    app = login(app, username='manager', password='manager')
-    app.get('/manage/check-type/group/add/', status=403)
-
-
-def test_edit_group(app, admin_user):
-    group = CheckTypeGroup.objects.create(label='Foo bar')
-    group2 = CheckTypeGroup.objects.create(label='baz')
-
-    app = login(app)
-    resp = app.get('/manage/check-types/')
-    resp = resp.click(href='/manage/check-type/group/%s/edit/' % group.pk)
-    resp.form['label'] = 'Foo bar baz'
-    resp.form['slug'] = group2.slug
-    resp = resp.form.submit()
-    assert resp.context['form'].errors['slug'] == ['Check type group with this Identifier already exists.']
-
-    resp.form['slug'] = 'baz2'
-    resp = resp.form.submit()
-    assert resp.location.endswith('/manage/check-types/')
-    group.refresh_from_db()
-    assert group.label == 'Foo bar baz'
-    assert group.slug == 'baz2'
-
-
-def test_edit_group_as_manager(app, manager_user, agenda_with_restrictions):
-    group = CheckTypeGroup.objects.create(label='Foo bar')
-
-    app = login(app, username='manager', password='manager')
-    app.get('/manage/check-type/group/%s/edit/' % group.pk, status=403)
-
-
-def test_delete_group(app, admin_user):
-    group = CheckTypeGroup.objects.create(label='Foo bar')
-    CheckType.objects.create(label='Foo reason', group=group)
-    agenda = Agenda.objects.create(label='Foo bar')
-    event = Event.objects.create(agenda=agenda, start_datetime=now(), places=10)
-    Booking.objects.create(event=event)
-
-    app = login(app)
-    resp = app.get('/manage/check-types/')
-    resp = resp.click(href='/manage/check-type/group/%s/delete/' % group.pk)
-    resp = resp.form.submit()
-    assert resp.location.endswith('/manage/check-types/')
-    assert CheckTypeGroup.objects.exists() is False
-    assert CheckType.objects.exists() is False
-
-
-def test_delete_group_as_manager(app, manager_user, agenda_with_restrictions):
-    group = CheckTypeGroup.objects.create(label='Foo bar')
-
-    app = login(app, username='manager', password='manager')
-    app.get('/manage/check-type/group/%s/delete/' % group.pk, status=403)
-
-
-def test_add_check_type(app, admin_user):
-    group = CheckTypeGroup.objects.create(label='Foo bar')
-
-    app = login(app)
-    resp = app.get('/manage/')
-    resp = resp.click('Check types')
-    resp = resp.click('Add a check type')
-    resp.form['label'] = 'Foo reason'
-    assert 'slug' not in resp.context['form'].fields
-    assert 'disabled' not in resp.context['form'].fields
-    resp = resp.form.submit()
-    check_type = CheckType.objects.latest('pk')
-    assert resp.location.endswith('/manage/check-types/')
-    assert check_type.label == 'Foo reason'
-    assert check_type.group == group
-    assert check_type.slug == 'foo-reason'
-    assert check_type.kind == 'absence'
-
-    resp = app.get('/manage/check-type/group/%s/add/' % group.pk)
-    resp.form['label'] = 'Foo reason'
-    resp.form['kind'] = 'presence'
-    resp = resp.form.submit()
-    assert resp.location.endswith('/manage/check-types/')
-    check_type = CheckType.objects.latest('pk')
-    assert check_type.label == 'Foo reason'
-    assert check_type.slug == 'foo-reason-1'
-    assert check_type.kind == 'presence'
-
-
-def test_add_check_type_as_manager(app, manager_user, agenda_with_restrictions):
-    group = CheckTypeGroup.objects.create(label='Foo bar')
-
-    app = login(app, username='manager', password='manager')
-    app.get('/manage/check-type/group/%s/add/' % group.pk, status=403)
-
-
-def test_edit_check_type(app, admin_user):
-    group = CheckTypeGroup.objects.create(label='Foo bar')
-    check_type = CheckType.objects.create(label='Foo reason', group=group, kind='presence')
-    check_type2 = CheckType.objects.create(label='Baz', group=group)
-    group2 = CheckTypeGroup.objects.create(label='Foo bar')
-    check_type3 = CheckType.objects.create(label='Foo bar reason', group=group2)
-    agenda = Agenda.objects.create(label='Foo bar')
-    event = Event.objects.create(agenda=agenda, start_datetime=now(), places=10)
-    Booking.objects.create(event=event)
-
-    app = login(app)
-    resp = app.get('/manage/check-types/')
-    resp = resp.click(href='/manage/check-type/group/%s/%s/edit/' % (group.pk, check_type.pk))
-    assert 'This check type is set on some existing bookings, modify it with caution.' not in resp
-    resp.form['label'] = 'Foo bar reason'
-    resp.form['slug'] = check_type2.slug
-    resp.form['disabled'] = True
-    assert 'kind' not in resp.context['form'].fields
-    resp = resp.form.submit()
-    assert resp.context['form'].errors['slug'] == ['Another check type exists with the same identifier.']
-
-    resp.form['slug'] = check_type3.slug
-    resp = resp.form.submit()
-    assert resp.location.endswith('/manage/check-types/')
-    check_type.refresh_from_db()
-    assert check_type.label == 'Foo bar reason'
-    assert check_type.slug == 'foo-bar-reason'
-    assert check_type.kind == 'presence'
-    assert check_type.disabled is True
-
-    # check_type is used
-    Booking.objects.update(user_check_type_slug=check_type.slug)
-    resp = app.get('/manage/check-type/group/%s/%s/edit/' % (group.pk, check_type.pk))
-    assert 'This check type is set on some existing bookings, modify it with caution.' in resp
-
-    app.get('/manage/check-type/group/%s/%s/edit/' % (group2.pk, check_type.pk), status=404)
-
-
-def test_edit_check_type_as_manager(app, manager_user, agenda_with_restrictions):
-    group = CheckTypeGroup.objects.create(label='Foo bar')
-    check_type = CheckType.objects.create(label='Foo reason', group=group)
-
-    app = login(app, username='manager', password='manager')
-    app.get('/manage/check-type/group/%s/%s/edit/' % (group.pk, check_type.pk), status=403)
-
-
-def test_delete_check_type(app, admin_user):
-    group = CheckTypeGroup.objects.create(label='Foo bar')
-    check_type = CheckType.objects.create(label='Foo reason', group=group)
-    agenda = Agenda.objects.create(label='Foo bar')
-    event = Event.objects.create(agenda=agenda, start_datetime=now(), places=10)
-    Booking.objects.create(event=event)
-
-    app = login(app)
-    resp = app.get('/manage/check-types/')
-    resp = resp.click(href='/manage/check-type/group/%s/%s/delete/' % (group.pk, check_type.pk))
-    resp = resp.form.submit()
-    assert resp.location.endswith('/manage/check-types/')
-    assert CheckTypeGroup.objects.exists() is True
-    assert CheckType.objects.exists() is False
-
-    # check_type is used
-    check_type = CheckType.objects.create(label='Foo reason', group=group)
-    Booking.objects.update(user_check_type_slug=check_type.slug)
-    resp = app.get('/manage/check-type/group/%s/%s/delete/' % (group.pk, check_type.pk))
-    assert 'Can not delete this check type: it is set on some existing bookings.' in resp
-    resp.form.submit(status=404)
-
-    group2 = CheckTypeGroup.objects.create(label='Foo bar baz')
-    app.get('/manage/check-type/group/%s/%s/delete/' % (group2.pk, check_type.pk), status=404)
-
-
-def test_delete_check_type_as_manager(app, manager_user, agenda_with_restrictions):
-    group = CheckTypeGroup.objects.create(label='Foo bar')
-    check_type = CheckType.objects.create(label='Foo reason', group=group)
-
-    app = login(app, username='manager', password='manager')
-    app.get('/manage/check-type/group/%s/%s/delete/' % (group.pk, check_type.pk), status=403)
-
-
-def test_meetings_agenda_group(app, admin_user):
-    agenda = Agenda.objects.create(label='Foo bar', kind='meetings')
-    CheckTypeGroup.objects.create(label='Foo bar')
-
-    app = login(app)
-    resp = app.get('/manage/agendas/%s/settings' % agenda.pk)
-    assert 'has_check_types' not in resp.context
-
-    # not for meetings agenda
-    app.get('/manage/agendas/%s/check-types' % agenda.pk, status=404)
-
-
-def test_agenda_group(app, admin_user):
-    agenda = Agenda.objects.create(label='Foo bar', kind='events')
-    Desk.objects.create(agenda=agenda, slug='_exceptions_holder')
-    event = Event.objects.create(agenda=agenda, start_datetime=now(), places=10)
-    booking = Booking.objects.create(event=event)
-
-    app = login(app)
-    resp = app.get('/manage/agendas/%s/settings' % agenda.pk)
-    assert 'has_check_types' in resp.context
-    assert resp.context['has_check_types'] is False
-    assert 'No check types configured for this agenda.' not in resp
-    assert '/manage/agendas/%s/check-types' % agenda.pk not in resp
-    resp = resp.click(href='/manage/agendas/%s/check-options' % agenda.pk)
-    assert 'check_type_group' not in resp.context['form'].fields
-
-    group = CheckTypeGroup.objects.create(label='Foo bar')
-    check_type = CheckType.objects.create(label='Foo reason', group=group)
-    resp = app.get('/manage/agendas/%s/settings' % agenda.pk)
-    assert 'has_check_types' in resp.context
-    assert resp.context['has_check_types'] is True
-    assert 'No check types configured for this agenda.' in resp
-    resp = resp.click(href='/manage/agendas/%s/check-options' % agenda.pk)
-    resp.form['check_type_group'] = group.pk
-    resp = resp.form.submit().follow()
-    agenda.refresh_from_db()
-    assert agenda.check_type_group == group
-    assert 'Check type group: Foo bar' in resp
-
-    # cannot change check_type group booking with non null check_type exists
-    booking.user_check_type_slug = check_type.slug
-    booking.save()
-    resp = app.get('/manage/agendas/%s/check-options' % agenda.pk)
-    assert 'check_type_group' not in resp.context['form'].fields
diff --git a/tests/manager/test_event.py b/tests/manager/test_event.py
index 3438442e..10ba2005 100644
--- a/tests/manager/test_event.py
+++ b/tests/manager/test_event.py
@@ -1782,7 +1782,7 @@ def test_event_check_filters(check_types, app, admin_user):
         resp = app.get(
             '/manage/agendas/%s/events/%s/check' % (agenda.pk, event.pk), params={'extra-data-foo': 'val1'}
         )
-        assert len(ctx.captured_queries) == 11
+        assert len(ctx.captured_queries) == 10
     assert 'User none' not in resp
     assert 'User empty' not in resp
     assert 'User foo-val1 bar-none presence' in resp
diff --git a/tests/manager/test_import_export.py b/tests/manager/test_import_export.py
index efd161e2..c0803c22 100644
--- a/tests/manager/test_import_export.py
+++ b/tests/manager/test_import_export.py
@@ -7,16 +7,7 @@ from django.utils.encoding import force_text
 from django.utils.timezone import now
 from webtest import Upload
 
-from chrono.agendas.models import (
-    Agenda,
-    Booking,
-    CheckType,
-    CheckTypeGroup,
-    Desk,
-    Event,
-    MeetingType,
-    UnavailabilityCalendar,
-)
+from chrono.agendas.models import Agenda, Booking, Desk, Event, MeetingType, UnavailabilityCalendar
 from tests.utils import login
 
 pytestmark = pytest.mark.django_db
@@ -36,7 +27,6 @@ def test_export_site(app, admin_user):
     assert site_json == {
         'unavailability_calendars': [],
         'agendas': [],
-        'check_type_groups': [],
         'events_types': [],
         'resources': [],
         'categories': [],
@@ -51,14 +41,12 @@ def test_export_site(app, admin_user):
     site_json = json.loads(resp.text)
     assert len(site_json['agendas']) == 1
     assert len(site_json['unavailability_calendars']) == 1
-    assert len(site_json['check_type_groups']) == 0
     assert len(site_json['events_types']) == 0
     assert len(site_json['resources']) == 0
     assert len(site_json['categories']) == 0
 
     resp = app.get('/manage/agendas/export/')
     resp.form['agendas'] = False
-    resp.form['check_type_groups'] = False
     resp.form['events_types'] = False
     resp.form['resources'] = False
     resp.form['categories'] = False
@@ -67,7 +55,6 @@ def test_export_site(app, admin_user):
     site_json = json.loads(resp.text)
     assert 'agendas' not in site_json
     assert 'unavailability_calendars' in site_json
-    assert 'check_type_groups' not in site_json
     assert 'events_types' not in site_json
     assert 'resources' not in site_json
     assert 'categories' not in site_json
@@ -291,70 +278,3 @@ def test_import_unavailability_calendar(app, admin_user):
     resp = resp.form.submit()
     assert 'Missing roles: &quot;gé1&quot;' in resp.text
     del calendar_export_dict['unavailability_calendars'][0]['permissions']['view']
-
-
-@pytest.mark.freeze_time('2021-07-08')
-def test_import_check_type_group(app, admin_user):
-    group = CheckTypeGroup.objects.create(label='Foo bar')
-    CheckType.objects.create(label='Foo reason', group=group)
-    CheckType.objects.create(label='Baz', group=group)
-
-    app = login(app)
-    resp = app.get('/manage/check-type/group/%s/export/' % group.id)
-    assert resp.headers['content-type'] == 'application/json'
-    assert (
-        resp.headers['content-disposition']
-        == 'attachment; filename="export_check_type_group_foo-bar_20210708.json"'
-    )
-    group_export = resp.text
-
-    # existing group
-    resp = app.get('/manage/', status=200)
-    resp = resp.click('Import')
-    resp.form['agendas_json'] = Upload('export.json', group_export.encode('utf-8'), 'application/json')
-    resp = resp.form.submit()
-    assert resp.location.endswith('/manage/check-types/')
-    resp = resp.follow()
-    assert 'No check type group created. A check type group has been updated.' not in resp.text
-    assert CheckTypeGroup.objects.count() == 1
-    assert CheckType.objects.count() == 2
-
-    # new group
-    CheckTypeGroup.objects.all().delete()
-    resp = app.get('/manage/', status=200)
-    resp = resp.click('Import')
-    resp.form['agendas_json'] = Upload('export.json', group_export.encode('utf-8'), 'application/json')
-    resp = resp.form.submit()
-    assert resp.location.endswith('/manage/check-types/')
-    resp = resp.follow()
-    assert 'A check type group has been created. No check type group updated.' not in resp.text
-    assert CheckTypeGroup.objects.count() == 1
-    assert CheckType.objects.count() == 2
-
-    # multiple groups
-    groups = json.loads(group_export)
-    groups['check_type_groups'].append(copy.copy(groups['check_type_groups'][0]))
-    groups['check_type_groups'].append(copy.copy(groups['check_type_groups'][0]))
-    groups['check_type_groups'][1]['label'] = 'Foo bar 2'
-    groups['check_type_groups'][1]['slug'] = 'foo-bar-2'
-    groups['check_type_groups'][2]['label'] = 'Foo bar 3'
-    groups['check_type_groups'][2]['slug'] = 'foo-bar-3'
-
-    resp = app.get('/manage/', status=200)
-    resp = resp.click('Import')
-    resp.form['agendas_json'] = Upload('export.json', json.dumps(groups).encode('utf-8'), 'application/json')
-    resp = resp.form.submit()
-    assert resp.location.endswith('/manage/')
-    resp = resp.follow()
-    assert '2 check type groups have been created. A check type group has been updated.' in resp.text
-    assert CheckTypeGroup.objects.count() == 3
-    assert CheckType.objects.count() == 6
-
-    CheckTypeGroup.objects.all().delete()
-    resp = app.get('/manage/', status=200)
-    resp = resp.click('Import')
-    resp.form['agendas_json'] = Upload('export.json', json.dumps(groups).encode('utf-8'), 'application/json')
-    resp = resp.form.submit().follow()
-    assert '3 check type groups have been created. No check type group updated.' in resp.text
-    assert CheckTypeGroup.objects.count() == 3
-    assert CheckType.objects.count() == 6
diff --git a/tests/test_agendas.py b/tests/test_agendas.py
index 570140d4..d7cc15cb 100644
--- a/tests/test_agendas.py
+++ b/tests/test_agendas.py
@@ -18,7 +18,6 @@ from chrono.agendas.models import (
     AgendaReminderSettings,
     Booking,
     Category,
-    CheckTypeGroup,
     Desk,
     Event,
     EventCancellationReport,
@@ -187,25 +186,6 @@ def test_category_duplicate_slugs():
     assert category.slug == 'foo-baz-2'
 
 
-def test_check_type_group_slug():
-    group = CheckTypeGroup.objects.create(label='Foo bar')
-    assert group.slug == 'foo-bar'
-
-
-def test_check_type_group_existing_slug():
-    group = CheckTypeGroup.objects.create(label='Foo bar', slug='bar')
-    assert group.slug == 'bar'
-
-
-def test_check_type_group_duplicate_slugs():
-    group = CheckTypeGroup.objects.create(label='Foo baz')
-    assert group.slug == 'foo-baz'
-    group = CheckTypeGroup.objects.create(label='Foo baz')
-    assert group.slug == 'foo-baz-1'
-    group = CheckTypeGroup.objects.create(label='Foo baz')
-    assert group.slug == 'foo-baz-2'
-
-
 def test_agenda_minimal_booking_delay(freezer):
     freezer.move_to('2021-07-09')
     agenda = Agenda.objects.create(label='Agenda', minimal_booking_delay=4)
diff --git a/tests/test_import_export.py b/tests/test_import_export.py
index c81cfb96..101deeee 100644
--- a/tests/test_import_export.py
+++ b/tests/test_import_export.py
@@ -21,8 +21,6 @@ from chrono.agendas.models import (
     AgendaNotificationsSettings,
     AgendaReminderSettings,
     Category,
-    CheckType,
-    CheckTypeGroup,
     Desk,
     Event,
     EventsType,
@@ -431,33 +429,6 @@ def test_import_export_agenda_with_category(app):
     assert agenda.category == category
 
 
-def test_import_export_agenda_with_check_types(app):
-    group = CheckTypeGroup.objects.create(label='foo')
-    agenda = Agenda.objects.create(label='Foo Bar', kind='events', check_type_group=group)
-    Desk.objects.create(agenda=agenda, slug='_exceptions_holder')
-    output = get_output_of_command('export_site')
-
-    import_site(data={}, clean=True)
-    assert Agenda.objects.count() == 0
-    assert CheckTypeGroup.objects.count() == 0
-    data = json.loads(output)
-    del data['check_type_groups']
-
-    with pytest.raises(AgendaImportError) as excinfo:
-        import_site(data, overwrite=True)
-    assert str(excinfo.value) == 'Missing "foo" check type group'
-
-    CheckTypeGroup.objects.create(label='foobar')
-    with pytest.raises(AgendaImportError) as excinfo:
-        import_site(data, overwrite=True)
-    assert str(excinfo.value) == 'Missing "foo" check type group'
-
-    group = CheckTypeGroup.objects.create(label='foo')
-    import_site(data, overwrite=True)
-    agenda = Agenda.objects.get(slug=agenda.slug)
-    assert agenda.check_type_group == group
-
-
 def test_import_export_agenda_with_events_type(app):
     events_type = EventsType.objects.create(label='foo')
     agenda = Agenda.objects.create(label='Foo Bar', kind='events', events_type=events_type)
@@ -932,63 +903,6 @@ def test_import_export_unavailability_calendar(app):
     assert calendar.label == 'Calendar Updated'
 
 
-def test_import_export_check_type_group(app):
-    output = get_output_of_command('export_site')
-    payload = json.loads(output)
-    assert len(payload['check_type_groups']) == 0
-
-    group = CheckTypeGroup.objects.create(label='Foo bar')
-    CheckType.objects.create(label='Foo reason', group=group)
-    CheckType.objects.create(label='Baz', group=group)
-
-    output = get_output_of_command('export_site')
-    payload = json.loads(output)
-    assert len(payload['check_type_groups']) == 1
-
-    group.delete()
-    assert not CheckTypeGroup.objects.exists()
-    assert not CheckType.objects.exists()
-
-    import_site(copy.deepcopy(payload))
-    assert CheckTypeGroup.objects.count() == 1
-    group = CheckTypeGroup.objects.first()
-    assert group.label == 'Foo bar'
-    assert group.slug == 'foo-bar'
-    assert group.check_types.count() == 2
-    assert CheckType.objects.get(group=group, label='Foo reason', slug='foo-reason')
-    assert CheckType.objects.get(group=group, label='Baz', slug='baz')
-
-    # update
-    update_payload = copy.deepcopy(payload)
-    update_payload['check_type_groups'][0]['label'] = 'Foo bar Updated'
-    import_site(update_payload)
-    group.refresh_from_db()
-    assert group.label == 'Foo bar Updated'
-
-    # insert another group
-    group.slug = 'foo-bar-updated'
-    group.save()
-    import_site(copy.deepcopy(payload))
-    assert CheckTypeGroup.objects.count() == 2
-    group = CheckTypeGroup.objects.latest('pk')
-    assert group.label == 'Foo bar'
-    assert group.slug == 'foo-bar'
-    assert group.check_types.count() == 2
-    assert CheckType.objects.get(group=group, label='Foo reason', slug='foo-reason')
-    assert CheckType.objects.get(group=group, label='Baz', slug='baz')
-
-    # with overwrite
-    CheckType.objects.create(group=group, label='Baz2')
-    import_site(copy.deepcopy(payload), overwrite=True)
-    assert CheckTypeGroup.objects.count() == 2
-    group = CheckTypeGroup.objects.latest('pk')
-    assert group.label == 'Foo bar'
-    assert group.slug == 'foo-bar'
-    assert group.check_types.count() == 2
-    assert CheckType.objects.get(group=group, label='Foo reason', slug='foo-reason')
-    assert CheckType.objects.get(group=group, label='Baz', slug='baz')
-
-
 def test_import_export_category(app):
     output = get_output_of_command('export_site')
     payload = json.loads(output)
-- 
2.35.1

