From efed292e547adf97364febe87ff2b3d2fdf4aa1d Mon Sep 17 00:00:00 2001 From: Valentin Deniaud Date: Wed, 29 Jun 2022 11:38:33 +0200 Subject: [PATCH] agendas: prevent cascade deletion of custody holiday rules (#66326) --- .../migrations/0133_auto_20220628_1600.py | 23 +++++++++++++++++++ chrono/agendas/models.py | 2 +- chrono/manager/views.py | 10 ++++++++ tests/manager/test_shared_custody_agenda.py | 6 +++++ 4 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 chrono/agendas/migrations/0133_auto_20220628_1600.py diff --git a/chrono/agendas/migrations/0133_auto_20220628_1600.py b/chrono/agendas/migrations/0133_auto_20220628_1600.py new file mode 100644 index 00000000..848d9d9c --- /dev/null +++ b/chrono/agendas/migrations/0133_auto_20220628_1600.py @@ -0,0 +1,23 @@ +# Generated by Django 2.2.26 on 2022-06-28 14:00 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('agendas', '0132_sharedcustodysettings_holidays_calendar'), + ] + + operations = [ + migrations.AlterField( + model_name='sharedcustodyholidayrule', + name='holiday', + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to='agendas.TimePeriodExceptionGroup', + verbose_name='Holiday', + ), + ), + ] diff --git a/chrono/agendas/models.py b/chrono/agendas/models.py index f04834cf..bd0f9827 100644 --- a/chrono/agendas/models.py +++ b/chrono/agendas/models.py @@ -3369,7 +3369,7 @@ class SharedCustodyHolidayRule(models.Model): ] agenda = models.ForeignKey(SharedCustodyAgenda, on_delete=models.CASCADE, related_name='holiday_rules') - holiday = models.ForeignKey(TimePeriodExceptionGroup, verbose_name=_('Holiday'), on_delete=models.CASCADE) + holiday = models.ForeignKey(TimePeriodExceptionGroup, verbose_name=_('Holiday'), on_delete=models.PROTECT) years = models.CharField(_('Years'), choices=YEAR_CHOICES, blank=True, max_length=16) periodicity = models.CharField(_('Periodicity'), choices=PERIODICITY_CHOICES, blank=True, max_length=32) guardian = models.ForeignKey(Person, verbose_name=_('Guardian'), on_delete=models.CASCADE) diff --git a/chrono/manager/views.py b/chrono/manager/views.py index 0037c97a..8f76b37d 100644 --- a/chrono/manager/views.py +++ b/chrono/manager/views.py @@ -31,6 +31,7 @@ from django.contrib import messages from django.core.exceptions import PermissionDenied from django.db import IntegrityError, transaction from django.db.models import BooleanField, Count, Max, Min, Q, Value +from django.db.models.deletion import ProtectedError from django.http import Http404, HttpResponse, HttpResponseForbidden, HttpResponseRedirect from django.shortcuts import get_object_or_404, redirect, render from django.template.defaultfilters import title @@ -3561,6 +3562,15 @@ class UnavailabilityCalendarDeleteView(DeleteView): def get_success_url(self): return reverse('chrono-manager-unavailability-calendar-list') + def delete(self, request, *args, **kwargs): + try: + return super().delete(request, *args, **kwargs) + except ProtectedError: + messages.warning( + request, _('This calendar cannot be deleted because it is used by shared custody agendas.') + ) + return HttpResponseRedirect(self.get_object().get_absolute_url()) + unavailability_calendar_delete = UnavailabilityCalendarDeleteView.as_view() diff --git a/tests/manager/test_shared_custody_agenda.py b/tests/manager/test_shared_custody_agenda.py index 617e77a8..9f14c231 100644 --- a/tests/manager/test_shared_custody_agenda.py +++ b/tests/manager/test_shared_custody_agenda.py @@ -290,6 +290,12 @@ def test_shared_custody_agenda_holiday_rules(app, admin_user): resp = app.get('/manage/shared-custody/%s/2022/12/' % agenda.pk) assert 'John Doe (Vacances de Noël)' in resp.text + # calendar cannot be deleted + resp = app.get('/manage/unavailability-calendar/%s/settings' % unavailability_calendar.pk) + resp = resp.click('Delete') + resp = resp.form.submit().follow() + assert 'This calendar cannot be deleted because it is used by shared custody agendas.' in resp.text + def test_shared_custody_settings_feature_flag(app, admin_user, settings): settings.SHARED_CUSTODY_ENABLED = False