diff --git a/chrono/agendas/models.py b/chrono/agendas/models.py index 71b1bcdc..3c81830c 100644 --- a/chrono/agendas/models.py +++ b/chrono/agendas/models.py @@ -1146,6 +1146,7 @@ class Desk(models.Model): def import_json(cls, data): timeperiods = data.pop('timeperiods', []) exceptions = data.pop('exceptions', []) + sources = data.pop('exception_sources', []) data = clean_import_data(cls, data) desk, created = cls.objects.update_or_create(slug=data['slug'], agenda=data['agenda'], defaults=data) for timeperiod in timeperiods: @@ -1154,14 +1155,20 @@ class Desk(models.Model): for exception in exceptions: exception['desk'] = desk TimePeriodException.import_json(exception) + for source in sources: + source['desk'] = desk + TimePeriodExceptionSource.import_json(source) return desk def export_json(self): + time_period_exceptions = self.timeperiodexception_set.filter(source__settings_slug__isnull=True) + time_period_exception_sources = self.timeperiodexceptionsource_set.filter(settings_slug__isnull=False) return { 'label': self.label, 'slug': self.slug, - 'timeperiods': [time_period.export_json() for time_period in self.timeperiod_set.all()], - 'exceptions': [exception.export_json() for exception in self.timeperiodexception_set.all()], + 'timeperiods': [time_period.export_json() for time_period in self.timeperiod_set.filter()], + 'exceptions': [exception.export_json() for exception in time_period_exceptions], + 'exception_sources': [source.export_json() for source in time_period_exception_sources], } def duplicate(self, label=None, agenda_target=None): @@ -1485,6 +1492,22 @@ class TimePeriodExceptionSource(models.Model): self.enabled = False self.save() + @classmethod + def import_json(cls, data): + data = clean_import_data(cls, data) + source, _ = cls.objects.update_or_create(**data) + if source.enabled: + source.enable() + return source + + def export_json(self): + '''Export only sources from settings.''' + return { + 'settings_slug': self.settings_slug, + 'settings_label': self.settings_label, + 'enabled': self.enabled, + } + class UnavailabilityCalendar(models.Model): label = models.CharField(_('Label'), max_length=150) diff --git a/tests/test_import_export.py b/tests/test_import_export.py index acb536ff..643753c1 100644 --- a/tests/test_import_export.py +++ b/tests/test_import_export.py @@ -14,6 +14,7 @@ import tempfile import pytest from django.contrib.auth.models import Group from django.core.management import call_command, CommandError +from django.test import override_settings from django.utils.encoding import force_bytes from django.utils.timezone import make_aware, now @@ -25,6 +26,7 @@ from chrono.agendas.models import ( Resource, TimePeriod, TimePeriodException, + TimePeriodExceptionSource, AgendaImportError, MeetingType, VirtualMember, @@ -531,3 +533,35 @@ def test_import_export_reminder_settings(): # again - check OneToOneField import_site(payload) + + +@override_settings( + EXCEPTIONS_SOURCES={'holidays': {'class': 'workalendar.europe.France', 'label': 'Holidays'},} +) +def test_import_export_time_period_exception_source(): + agenda = Agenda.objects.create(label='Foo bar', kind='meetings') + desk = Desk.objects.create(slug='test', agenda=agenda) + desk.import_timeperiod_exceptions_from_settings(enable=True) + + output = get_output_of_command('export_site') + payload = json.loads(output) + + agenda.delete() + assert not TimePeriodExceptionSource.objects.exists() + + import_site(payload) + desk = Desk.objects.get(slug='test') + source = desk.timeperiodexceptionsource_set.first() + assert source.enabled + assert desk.timeperiodexception_set.exists() + + source.disable() + output = get_output_of_command('export_site') + payload = json.loads(output) + Agenda.objects.all().delete() + + import_site(payload) + desk = Desk.objects.get(slug='test') + source = desk.timeperiodexceptionsource_set.first() + assert not source.enabled + assert not desk.timeperiodexception_set.exists()