From fe16e1af83ed3e1c22189ac6e11d169e4df6a921 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laur=C3=A9line=20Gu=C3=A9rin?= Date: Fri, 13 May 2022 11:59:15 +0200 Subject: [PATCH] pricing: import/export pricing_data (#65053) --- chrono/agendas/models.py | 18 +++++++++- chrono/pricing/models.py | 19 +++++++++++ tests/test_import_export.py | 67 ++++++++++++++++++++++++++++++++++++- 3 files changed, 102 insertions(+), 2 deletions(-) diff --git a/chrono/agendas/models.py b/chrono/agendas/models.py index 583d1802..016dd4aa 100644 --- a/chrono/agendas/models.py +++ b/chrono/agendas/models.py @@ -404,6 +404,7 @@ class Agenda(models.Model): agenda['event_display_template'] = self.event_display_template agenda['mark_event_checked_auto'] = self.mark_event_checked_auto agenda['events_type'] = self.events_type.slug if self.events_type else None + agenda['pricings'] = [x.export_json() for x in self.agendapricing_set.all()] elif self.kind == 'meetings': agenda['meetingtypes'] = [x.export_json() for x in self.meetingtype_set.filter(deleted=False)] agenda['desks'] = [desk.export_json() for desk in self.desk_set.all()] @@ -415,13 +416,14 @@ class Agenda(models.Model): @classmethod def import_json(cls, data, overwrite=False): - data = data.copy() + data = copy.deepcopy(data) permissions = data.pop('permissions') or {} reminder_settings = data.pop('reminder_settings', None) if data['kind'] == 'events': events = data.pop('events') notifications_settings = data.pop('notifications_settings', None) exceptions_desk = data.pop('exceptions_desk', None) + pricings = data.pop('pricings', None) or [] elif data['kind'] == 'meetings': meetingtypes = data.pop('meetingtypes') desks = data.pop('desks') @@ -453,6 +455,14 @@ class Agenda(models.Model): data['events_type'] = EventsType.objects.get(slug=data['events_type']) except EventsType.DoesNotExist: raise AgendaImportError(_('Missing "%s" events type') % data['events_type']) + if data['kind'] == 'events' and pricings: + from chrono.pricing.models import Pricing + + for pricing_data in pricings: + try: + pricing_data['pricing'] = Pricing.objects.get(slug=pricing_data['pricing']) + except Pricing.DoesNotExist: + raise AgendaImportError(_('Missing "%s" pricing model') % pricing_data['pricing']) agenda, created = cls.objects.update_or_create(slug=data['slug'], defaults=data) if overwrite: AgendaReminderSettings.objects.filter(agenda=agenda).delete() @@ -463,12 +473,18 @@ class Agenda(models.Model): if overwrite: Event.objects.filter(agenda=agenda).delete() AgendaNotificationsSettings.objects.filter(agenda=agenda).delete() + agenda.agendapricing_set.all().delete() for event_data in events: event_data['agenda'] = agenda Event.import_json(event_data) if notifications_settings: notifications_settings['agenda'] = agenda AgendaNotificationsSettings.import_json(notifications_settings) + for pricing_data in pricings: + from chrono.pricing.models import AgendaPricing + + pricing_data['agenda'] = agenda + AgendaPricing.import_json(pricing_data) if exceptions_desk: exceptions_desk['agenda'] = agenda Desk.import_json(exceptions_desk) diff --git a/chrono/pricing/models.py b/chrono/pricing/models.py index 48d11c2d..f4905956 100644 --- a/chrono/pricing/models.py +++ b/chrono/pricing/models.py @@ -306,6 +306,25 @@ class AgendaPricing(models.Model): date_end = models.DateField() pricing_data = JSONField(null=True) + @classmethod + def import_json(cls, data): + data = clean_import_data(cls, data) + cls.objects.update_or_create( + agenda=data['agenda'], + pricing=data['pricing'], + date_start=data['date_start'], + date_end=data['date_end'], + defaults=data, + ) + + def export_json(self): + return { + 'pricing': self.pricing.slug, + 'date_start': self.date_start.strftime('%Y-%m-%d'), + 'date_end': self.date_end.strftime('%Y-%m-%d'), + 'pricing_data': self.pricing_data, + } + @staticmethod def get_pricing_data(request, event, user_external_id, adult_external_id): agenda_pricing = AgendaPricing.get_agenda_pricing(event) diff --git a/tests/test_import_export.py b/tests/test_import_export.py index 523f558a..b5aaf7d9 100644 --- a/tests/test_import_export.py +++ b/tests/test_import_export.py @@ -35,7 +35,7 @@ from chrono.agendas.models import ( VirtualMember, ) from chrono.manager.utils import import_site -from chrono.pricing.models import Criteria, CriteriaCategory, Pricing, PricingCriteriaCategory +from chrono.pricing.models import AgendaPricing, Criteria, CriteriaCategory, Pricing, PricingCriteriaCategory pytestmark = pytest.mark.django_db @@ -486,6 +486,71 @@ def test_import_export_agenda_with_events_type(app): assert agenda.events_type == events_type +def test_import_export_agenda_with_pricing(app): + pricing = Pricing.objects.create(label='Foo') + agenda = Agenda.objects.create(label='Foo Bar', kind='events') + Desk.objects.create(agenda=agenda, slug='_exceptions_holder') + agenda_pricing = AgendaPricing.objects.create( + agenda=agenda, + pricing=pricing, + date_start=datetime.date(year=2021, month=9, day=1), + date_end=datetime.date(year=2021, month=10, day=1), + pricing_data={ + 'foo': 'bar', + }, + ) + output = get_output_of_command('export_site') + + import_site(data={}, clean=True) + assert Agenda.objects.count() == 0 + assert Pricing.objects.count() == 0 + data = json.loads(output) + del data['pricing_models'] + print(data) + + with pytest.raises(AgendaImportError) as excinfo: + import_site(data, overwrite=True) + assert str(excinfo.value) == 'Missing "foo" pricing model' + + Pricing.objects.create(label='foobar') + with pytest.raises(AgendaImportError) as excinfo: + import_site(data, overwrite=True) + assert str(excinfo.value) == 'Missing "foo" pricing model' + + pricing = Pricing.objects.create(label='Foo') + import_site(data, overwrite=True) + agenda = Agenda.objects.get(slug=agenda.slug) + assert agenda.agendapricing_set.count() == 1 + agenda_pricing = agenda.agendapricing_set.get() + assert agenda_pricing.agenda == agenda + assert agenda_pricing.pricing == pricing + assert agenda_pricing.date_start == datetime.date(year=2021, month=9, day=1) + assert agenda_pricing.date_end == datetime.date(year=2021, month=10, day=1) + + # again + import_site(data) + assert agenda.agendapricing_set.count() == 1 + agenda_pricing = AgendaPricing.objects.get(pk=agenda_pricing.pk) + assert agenda_pricing.agenda == agenda + assert agenda_pricing.pricing == pricing + + data['agendas'][0]['pricings'].append( + { + 'pricing': 'foo', + 'date_start': '2022-09-01', + 'date_end': '2022-10-01', + 'pricing_data': {'foo': 'bar'}, + } + ) + import_site(data) + assert agenda.agendapricing_set.count() == 2 + agenda_pricing = AgendaPricing.objects.latest('pk') + assert agenda_pricing.agenda == agenda + assert agenda_pricing.pricing == pricing + assert agenda_pricing.date_start == datetime.date(year=2022, month=9, day=1) + assert agenda_pricing.date_end == datetime.date(year=2022, month=10, day=1) + + def test_import_export_virtual_agenda(app): virtual_agenda = Agenda.objects.create(label='Virtual Agenda', kind='virtual') output = get_output_of_command('export_site')