From c41f1a25952d05653824631f2ffd51bc141dd3ee Mon Sep 17 00:00:00 2001 From: Valentin Deniaud Date: Tue, 28 Jun 2022 15:17:57 +0200 Subject: [PATCH 1/2] manager: select unavailability calendar containing holidays (#66326) --- ...sharedcustodysettings_holidays_calendar.py | 26 +++++++++++++++++++ chrono/agendas/models.py | 21 ++++++++++++++- chrono/manager/forms.py | 3 ++- chrono/manager/utils.py | 2 +- chrono/manager/views.py | 2 +- tests/api/test_shared_custody.py | 5 ++-- tests/manager/test_shared_custody_agenda.py | 7 +++-- tests/test_import_export.py | 12 +++++++-- 8 files changed, 68 insertions(+), 10 deletions(-) create mode 100644 chrono/agendas/migrations/0132_sharedcustodysettings_holidays_calendar.py diff --git a/chrono/agendas/migrations/0132_sharedcustodysettings_holidays_calendar.py b/chrono/agendas/migrations/0132_sharedcustodysettings_holidays_calendar.py new file mode 100644 index 00000000..2e94ce82 --- /dev/null +++ b/chrono/agendas/migrations/0132_sharedcustodysettings_holidays_calendar.py @@ -0,0 +1,26 @@ +# Generated by Django 2.2.26 on 2022-06-28 12:56 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('agendas', '0131_sharedcustodysettings'), + ] + + operations = [ + migrations.AddField( + model_name='sharedcustodysettings', + name='holidays_calendar', + field=models.ForeignKey( + blank=True, + null=True, + related_name='+', + on_delete=django.db.models.deletion.SET_NULL, + to='agendas.UnavailabilityCalendar', + verbose_name='Holidays calendar', + ), + ), + ] diff --git a/chrono/agendas/models.py b/chrono/agendas/models.py index 97fb11d9..f04834cf 100644 --- a/chrono/agendas/models.py +++ b/chrono/agendas/models.py @@ -3499,15 +3499,34 @@ class SharedCustodySettings(models.Model): verbose_name=_('Management role'), on_delete=models.SET_NULL, ) + holidays_calendar = models.ForeignKey( + UnavailabilityCalendar, + verbose_name=_('Holidays calendar'), + null=True, + blank=True, + related_name='+', + on_delete=models.SET_NULL, + ) def export_json(self): - return {'management_role': self.management_role.name if self.management_role else None} + return { + 'management_role': self.management_role.name if self.management_role else None, + 'holidays_calendar': self.holidays_calendar.slug if self.holidays_calendar else None, + } @classmethod def import_json(cls, data): if data.get('management_role'): data['management_role'] = Group.objects.get(name=data['management_role']) + if data.get('holidays_calendar'): + try: + data['holidays_calendar'] = UnavailabilityCalendar.objects.get(slug=data['holidays_calendar']) + except UnavailabilityCalendar.DoesNotExist: + raise AgendaImportError( + _('The unavailability calendar "%s" does not exist.') % data['holidays_calendar'] + ) + cls.objects.update_or_create(defaults=data) @classmethod diff --git a/chrono/manager/forms.py b/chrono/manager/forms.py index 7b0194f2..8f2a4ad7 100644 --- a/chrono/manager/forms.py +++ b/chrono/manager/forms.py @@ -1498,8 +1498,9 @@ class SharedCustodyHolidayRuleForm(forms.ModelForm): self.fields['guardian'].queryset = Person.objects.filter( pk__in=[self.instance.agenda.first_guardian_id, self.instance.agenda.second_guardian_id] ) + settings = SharedCustodySettings.get_singleton() self.fields['holiday'].queryset = TimePeriodExceptionGroup.objects.filter( - unavailability_calendar__slug='chrono-holidays', + unavailability_calendar=settings.holidays_calendar_id, exceptions__isnull=False, ).distinct() diff --git a/chrono/manager/utils.py b/chrono/manager/utils.py index 80d7d9b1..9290fb39 100644 --- a/chrono/manager/utils.py +++ b/chrono/manager/utils.py @@ -77,12 +77,12 @@ def import_site(data, if_empty=False, clean=False, overwrite=False): if clean: Agenda.objects.all().delete() + SharedCustodySettings.objects.all().delete() UnavailabilityCalendar.objects.all().delete() CheckTypeGroup.objects.all().delete() EventsType.objects.all().delete() Resource.objects.all().delete() Category.objects.all().delete() - SharedCustodySettings.objects.all().delete() results = { key: collections.defaultdict(list) diff --git a/chrono/manager/views.py b/chrono/manager/views.py index 0f4ad4fc..0037c97a 100644 --- a/chrono/manager/views.py +++ b/chrono/manager/views.py @@ -3772,7 +3772,7 @@ class SharedCustodyAgendaSettings(SharedCustodyAgendaMixin, DetailView): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - context['has_holidays'] = UnavailabilityCalendar.objects.filter(slug='chrono-holidays').exists() + context['has_holidays'] = bool(SharedCustodySettings.get_singleton().holidays_calendar_id) context['exceptional_periods'] = SharedCustodyPeriod.objects.filter(holiday_rule__isnull=True) return context diff --git a/tests/api/test_shared_custody.py b/tests/api/test_shared_custody.py index 2a4e3da8..459febff 100644 --- a/tests/api/test_shared_custody.py +++ b/tests/api/test_shared_custody.py @@ -1,7 +1,7 @@ import pytest from django.core.files.base import ContentFile -from chrono.agendas.models import Person, SharedCustodyAgenda, UnavailabilityCalendar +from chrono.agendas.models import Person, SharedCustodyAgenda, SharedCustodySettings, UnavailabilityCalendar pytestmark = pytest.mark.django_db @@ -74,7 +74,8 @@ def test_add_shared_custody_agenda_with_rules(app, user, settings): app.authorization = ('Basic', ('john.doe', 'password')) # configure holidays - unavailability_calendar = UnavailabilityCalendar.objects.create(label='Calendar', slug='chrono-holidays') + unavailability_calendar = UnavailabilityCalendar.objects.create(label='Calendar') + SharedCustodySettings.objects.create(holidays_calendar=unavailability_calendar) source = unavailability_calendar.timeperiodexceptionsource_set.create( ics_filename='holidays.ics', ics_file=ContentFile(ICS_HOLIDAYS, name='holidays.ics') ) diff --git a/tests/manager/test_shared_custody_agenda.py b/tests/manager/test_shared_custody_agenda.py index 97723cae..617e77a8 100644 --- a/tests/manager/test_shared_custody_agenda.py +++ b/tests/manager/test_shared_custody_agenda.py @@ -11,6 +11,7 @@ from chrono.agendas.models import ( SharedCustodyHolidayRule, SharedCustodyPeriod, SharedCustodyRule, + SharedCustodySettings, TimePeriodExceptionGroup, UnavailabilityCalendar, ) @@ -188,7 +189,8 @@ def test_shared_custody_agenda_month_view_queries(app, admin_user): ) # configure holidays - unavailability_calendar = UnavailabilityCalendar.objects.create(label='Calendar', slug='chrono-holidays') + unavailability_calendar = UnavailabilityCalendar.objects.create(label='Calendar') + SharedCustodySettings.objects.create(holidays_calendar=unavailability_calendar) source = unavailability_calendar.timeperiodexceptionsource_set.create( ics_filename='holidays.ics', ics_file=ContentFile(ICS_HOLIDAYS, name='holidays.ics') ) @@ -217,7 +219,8 @@ def test_shared_custody_agenda_holiday_rules(app, admin_user): assert 'Custody rules during holidays' not in resp.text # configure holidays - unavailability_calendar = UnavailabilityCalendar.objects.create(label='Calendar', slug='chrono-holidays') + unavailability_calendar = UnavailabilityCalendar.objects.create(label='Calendar') + SharedCustodySettings.objects.create(holidays_calendar=unavailability_calendar) source = unavailability_calendar.timeperiodexceptionsource_set.create( ics_filename='holidays.ics', ics_file=ContentFile(ICS_HOLIDAYS, name='holidays.ics') ) diff --git a/tests/test_import_export.py b/tests/test_import_export.py index 17cbdc08..70affe46 100644 --- a/tests/test_import_export.py +++ b/tests/test_import_export.py @@ -1235,22 +1235,30 @@ def test_import_export_agenda_update(app): def test_import_export_shared_custody_settings(app): group = Group.objects.create(name='test') - SharedCustodySettings.objects.create(management_role=group) + calendar = UnavailabilityCalendar.objects.create(label='Calendar') + SharedCustodySettings.objects.create(management_role=group, holidays_calendar=calendar) output = get_output_of_command('export_site') import_site(data={}, clean=True) assert SharedCustodySettings.get_singleton().management_role is None Group.objects.all().delete() + payload = json.loads(output) + del payload['unavailability_calendars'] with pytest.raises(AgendaImportError) as excinfo: - import_site(json.loads(output)) + import_site(payload) assert '%s' % excinfo.value == 'Missing roles: "test"' group = Group.objects.create(name='test') + with pytest.raises(AgendaImportError) as excinfo: + import_site(payload) + assert '%s' % excinfo.value == 'The unavailability calendar "calendar" does not exist.' + import_site(json.loads(output)) settings = SharedCustodySettings.get_singleton() assert settings.management_role == group + assert settings.holidays_calendar.slug == calendar.slug group2 = Group.objects.create(name='test2') settings.management_role = group2 -- 2.30.2