pricing: import/export pricings (#67196)
This commit is contained in:
parent
c694ee5e67
commit
369fbb8602
|
@ -52,25 +52,16 @@ class Agenda(models.Model):
|
|||
def export_json(self):
|
||||
return {
|
||||
'slug': self.slug,
|
||||
'pricings': [x.export_json() for x in self.old_agendapricings.all()],
|
||||
'check_type_group': self.check_type_group.slug if self.check_type_group else None,
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def import_json(cls, data, overwrite=False):
|
||||
from lingo.pricing.models import AgendaPricing, Pricing
|
||||
|
||||
data = copy.deepcopy(data)
|
||||
try:
|
||||
agenda = Agenda.objects.get(slug=data['slug'])
|
||||
except Agenda.DoesNotExist:
|
||||
raise AgendaImportError(_('Missing "%s" agenda') % data['slug'])
|
||||
pricings = data.pop('pricings', None) or []
|
||||
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'])
|
||||
if data.get('check_type_group'):
|
||||
try:
|
||||
data['check_type_group'] = CheckTypeGroup.objects.get(slug=data['check_type_group'])
|
||||
|
@ -80,10 +71,6 @@ class Agenda(models.Model):
|
|||
agenda.check_type_group = data.get('check_type_group')
|
||||
agenda.save()
|
||||
|
||||
for pricing_data in pricings:
|
||||
pricing_data['agenda'] = agenda
|
||||
AgendaPricing.import_json(pricing_data)
|
||||
|
||||
return False, agenda
|
||||
|
||||
def get_chrono_url(self):
|
||||
|
|
|
@ -34,6 +34,7 @@ class ExportForm(forms.Form):
|
|||
label=_('Pricing criteria categories'), required=False, initial=True
|
||||
)
|
||||
pricing_models = forms.BooleanField(label=_('Pricing models'), required=False, initial=True)
|
||||
pricings = forms.BooleanField(label=_('Pricings'), required=False, initial=True)
|
||||
|
||||
|
||||
class ImportForm(forms.Form):
|
||||
|
|
|
@ -343,25 +343,42 @@ 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,
|
||||
'agendas': [a.slug for a in self.agendas.all()],
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def import_json(cls, data, overwrite=False):
|
||||
data = copy.deepcopy(data)
|
||||
agenda_slugs = data.pop('agendas', None) or []
|
||||
data = clean_import_data(cls, data)
|
||||
agendas = []
|
||||
for agenda_slug in agenda_slugs:
|
||||
try:
|
||||
agendas.append(Agenda.objects.get(slug=agenda_slug))
|
||||
except Agenda.DoesNotExist:
|
||||
raise AgendaImportError(_('Missing "%s" agenda') % agenda_slug)
|
||||
try:
|
||||
data['pricing'] = Pricing.objects.get(slug=data['pricing'])
|
||||
except Pricing.DoesNotExist:
|
||||
raise AgendaImportError(_('Missing "%s" pricing model') % data['pricing'])
|
||||
|
||||
agenda_pricing, created = cls.objects.update_or_create(
|
||||
pricing=data['pricing'],
|
||||
date_start=data['date_start'],
|
||||
date_end=data['date_end'],
|
||||
defaults=data,
|
||||
)
|
||||
if overwrite and not created:
|
||||
agenda_pricing.agendas.clear()
|
||||
agenda_pricing.agendas.add(*agendas)
|
||||
return created, agenda_pricing
|
||||
|
||||
@staticmethod
|
||||
def get_pricing_data(
|
||||
request,
|
||||
|
|
|
@ -27,9 +27,12 @@ def export_site(
|
|||
check_type_groups=True,
|
||||
pricing_categories=True,
|
||||
pricing_models=True,
|
||||
pricings=True,
|
||||
):
|
||||
'''Dump site objects to JSON-dumpable dictionnary'''
|
||||
data = collections.OrderedDict()
|
||||
if pricings:
|
||||
data['pricings'] = [x.export_json() for x in AgendaPricing.objects.all()]
|
||||
if pricing_models:
|
||||
data['pricing_models'] = [x.export_json() for x in Pricing.objects.all()]
|
||||
if pricing_categories:
|
||||
|
@ -63,6 +66,7 @@ def import_site(data, if_empty=False, clean=False, overwrite=False):
|
|||
'check_type_groups',
|
||||
'pricing_categories',
|
||||
'pricing_models',
|
||||
'pricings',
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -72,6 +76,7 @@ def import_site(data, if_empty=False, clean=False, overwrite=False):
|
|||
(Pricing, 'pricing_models'),
|
||||
(CheckTypeGroup, 'check_type_groups'),
|
||||
(Agenda, 'agendas'),
|
||||
(AgendaPricing, 'pricings'),
|
||||
):
|
||||
objs = data.get(key, [])
|
||||
for obj in objs:
|
||||
|
|
|
@ -151,6 +151,20 @@ class ConfigImportView(FormView):
|
|||
x,
|
||||
),
|
||||
},
|
||||
'pricings': {
|
||||
'create_noop': _('No pricing created.'),
|
||||
'create': lambda x: ungettext(
|
||||
'A pricing has been created.',
|
||||
'%(count)d pricings have been created.',
|
||||
x,
|
||||
),
|
||||
'update_noop': _('No pricing updated.'),
|
||||
'update': lambda x: ungettext(
|
||||
'A pricing has been updated.',
|
||||
'%(count)d pricings have been updated.',
|
||||
x,
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
global_noop = True
|
||||
|
@ -192,7 +206,7 @@ class ConfigImportView(FormView):
|
|||
# only one criteria category imported, redirect to criteria page
|
||||
return HttpResponseRedirect(reverse('lingo-manager-pricing-criteria-list'))
|
||||
if (a_count, ct_count, pc_count, pm_count) == (0, 0, 0, 1):
|
||||
# only one pricing imported, redirect to pricing page
|
||||
# only one pricing model imported, redirect to pricing model page
|
||||
return HttpResponseRedirect(
|
||||
reverse(
|
||||
'lingo-manager-pricing-detail',
|
||||
|
@ -207,6 +221,7 @@ class ConfigImportView(FormView):
|
|||
messages.info(self.request, results['check_type_groups']['messages'])
|
||||
messages.info(self.request, results['pricing_categories']['messages'])
|
||||
messages.info(self.request, results['pricing_models']['messages'])
|
||||
messages.info(self.request, results['pricings']['messages'])
|
||||
|
||||
return super().form_valid(form)
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ def test_export_site(freezer, app, admin_user):
|
|||
'check_type_groups': [],
|
||||
'pricing_categories': [],
|
||||
'pricing_models': [],
|
||||
'pricings': [],
|
||||
}
|
||||
|
||||
Agenda.objects.create(label='Foo Bar')
|
||||
|
@ -41,6 +42,7 @@ def test_export_site(freezer, app, admin_user):
|
|||
resp.form['check_type_groups'] = False
|
||||
resp.form['pricing_categories'] = False
|
||||
resp.form['pricing_models'] = False
|
||||
resp.form['pricings'] = False
|
||||
resp = resp.form.submit()
|
||||
|
||||
site_json = json.loads(resp.text)
|
||||
|
@ -48,6 +50,7 @@ def test_export_site(freezer, app, admin_user):
|
|||
assert 'check_type_groups' not in site_json
|
||||
assert 'pricing_categories' not in site_json
|
||||
assert 'pricing_models' not in site_json
|
||||
assert 'pricings' not in site_json
|
||||
|
||||
|
||||
@pytest.mark.freeze_time('2021-07-08')
|
||||
|
|
|
@ -28,10 +28,9 @@ def get_output_of_command(command, *args, **kwargs):
|
|||
|
||||
|
||||
def test_import_export(app):
|
||||
agenda = Agenda.objects.create(label='Foo Bar')
|
||||
Agenda.objects.create(label='Foo Bar')
|
||||
pricing = Pricing.objects.create(label='Foo')
|
||||
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),
|
||||
|
@ -40,12 +39,14 @@ def test_import_export(app):
|
|||
|
||||
output = get_output_of_command('export_pricing_config')
|
||||
assert len(json.loads(output)['agendas']) == 1
|
||||
assert len(json.loads(output)['pricings']) == 1
|
||||
assert len(json.loads(output)['pricings'][0]['agendas']) == 0
|
||||
assert len(json.loads(output)['pricing_models']) == 1
|
||||
assert len(json.loads(output)['pricing_categories']) == 1
|
||||
import_site(data={}, clean=True)
|
||||
empty_output = get_output_of_command('export_pricing_config')
|
||||
assert len(json.loads(empty_output)['agendas']) == 1
|
||||
assert len(json.loads(empty_output)['agendas'][0]['pricings']) == 0
|
||||
assert len(json.loads(empty_output)['pricings']) == 0
|
||||
assert len(json.loads(empty_output)['pricing_models']) == 0
|
||||
assert len(json.loads(empty_output)['pricing_categories']) == 0
|
||||
|
||||
|
@ -53,7 +54,6 @@ def test_import_export(app):
|
|||
sys.stdin = StringIO(json.dumps({}))
|
||||
pricing = Pricing.objects.create(label='Foo')
|
||||
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),
|
||||
|
@ -92,11 +92,10 @@ def test_import_export(app):
|
|||
shutil.rmtree(tempdir)
|
||||
|
||||
|
||||
def test_import_export_agenda_with_pricing(app):
|
||||
def test_import_export_agenda_pricing(app):
|
||||
pricing = Pricing.objects.create(label='Foo')
|
||||
agenda = Agenda.objects.create(label='Foo Bar')
|
||||
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),
|
||||
|
@ -104,59 +103,61 @@ def test_import_export_agenda_with_pricing(app):
|
|||
'foo': 'bar',
|
||||
},
|
||||
)
|
||||
agenda_pricing.agendas.set([agenda])
|
||||
output = get_output_of_command('export_pricing_config')
|
||||
|
||||
import_site(data={}, clean=True)
|
||||
assert Pricing.objects.count() == 0
|
||||
data = json.loads(output)
|
||||
del data['pricing_models']
|
||||
|
||||
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'
|
||||
|
||||
Agenda.objects.all().delete()
|
||||
pricing = Pricing.objects.create(label='Foo')
|
||||
with pytest.raises(AgendaImportError) as excinfo:
|
||||
import_site(data, overwrite=True)
|
||||
assert str(excinfo.value) == 'Missing "foo-bar" agenda'
|
||||
|
||||
agenda2 = Agenda.objects.create(label='Baz')
|
||||
with pytest.raises(AgendaImportError) as excinfo:
|
||||
import_site(data, overwrite=True)
|
||||
assert str(excinfo.value) == 'Missing "foo-bar" agenda'
|
||||
|
||||
del data['pricing_models']
|
||||
Pricing.objects.all().delete()
|
||||
agenda = Agenda.objects.create(label='Foo Bar')
|
||||
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)
|
||||
assert agenda.old_agendapricings.count() == 1
|
||||
agenda_pricing = agenda.old_agendapricings.get()
|
||||
assert agenda_pricing.agenda == agenda
|
||||
agenda_pricing = AgendaPricing.objects.latest('pk')
|
||||
assert list(agenda_pricing.agendas.all()) == [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)
|
||||
assert agenda_pricing.pricing_data == {'foo': 'bar'}
|
||||
|
||||
# again
|
||||
import_site(data)
|
||||
assert agenda.old_agendapricings.count() == 1
|
||||
agenda_pricing = AgendaPricing.objects.get(pk=agenda_pricing.pk)
|
||||
assert agenda_pricing.agenda == agenda
|
||||
assert list(agenda_pricing.agendas.all()) == [agenda]
|
||||
assert agenda_pricing.pricing == pricing
|
||||
|
||||
data['agendas'][0]['pricings'].append(
|
||||
data['pricings'].append(
|
||||
{
|
||||
'pricing': 'foo',
|
||||
'agendas': ['foo-bar', 'baz'],
|
||||
'date_start': '2022-09-01',
|
||||
'date_end': '2022-10-01',
|
||||
'pricing_data': {'foo': 'bar'},
|
||||
}
|
||||
)
|
||||
import_site(data)
|
||||
assert agenda.old_agendapricings.count() == 2
|
||||
agenda_pricing = AgendaPricing.objects.latest('pk')
|
||||
assert agenda_pricing.agenda == agenda
|
||||
assert list(agenda_pricing.agendas.all().order_by('slug')) == [agenda2, 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)
|
||||
assert agenda_pricing.pricing_data == {'foo': 'bar'}
|
||||
|
||||
|
||||
def test_import_export_agenda_with_check_types(app):
|
||||
|
|
Loading…
Reference in New Issue