diff --git a/lingo/pricing/templates/lingo/pricing/manager_agenda_pricing_detail.html b/lingo/pricing/templates/lingo/pricing/manager_agenda_pricing_detail.html
index 908d499..a24a340 100644
--- a/lingo/pricing/templates/lingo/pricing/manager_agenda_pricing_detail.html
+++ b/lingo/pricing/templates/lingo/pricing/manager_agenda_pricing_detail.html
@@ -15,6 +15,7 @@
diff --git a/lingo/pricing/urls.py b/lingo/pricing/urls.py
index 473e808..ded8c7c 100644
--- a/lingo/pricing/urls.py
+++ b/lingo/pricing/urls.py
@@ -178,6 +178,11 @@ urlpatterns = [
views.agenda_pricing_delete,
name='lingo-manager-agenda-pricing-delete',
),
+ url(
+ r'^agenda-pricing/(?P\d+)/export/$',
+ views.agenda_pricing_export,
+ name='lingo-manager-agenda-pricing-export',
+ ),
url(
r'^agenda-pricing/(?P\d+)/matrix/edit/$',
views.agenda_pricing_matrix_edit,
diff --git a/lingo/pricing/views.py b/lingo/pricing/views.py
index e120dd9..fb62e35 100644
--- a/lingo/pricing/views.py
+++ b/lingo/pricing/views.py
@@ -192,15 +192,19 @@ class ConfigImportView(FormView):
else:
message2 = import_messages[obj_name]['update'](count) % {'count': count}
- obj_results['messages'] = "%s %s" % (message1, message2)
+ if message1:
+ obj_results['messages'] = "%s %s" % (message1, message2)
+ else:
+ obj_results['messages'] = message2
- a_count, ct_count, pc_count, pm_count = (
+ a_count, ct_count, pc_count, pm_count, p_count = (
len(results['agendas']['all']),
len(results['check_type_groups']['all']),
len(results['pricing_categories']['all']),
len(results['pricing_models']['all']),
+ len(results['pricings']['all']),
)
- if (a_count, ct_count, pc_count, pm_count) == (1, 0, 0, 0):
+ if (a_count, ct_count, pc_count, pm_count, p_count) == (1, 0, 0, 0, 0):
# only one agenda imported, redirect to agenda page
return HttpResponseRedirect(
reverse(
@@ -208,13 +212,13 @@ class ConfigImportView(FormView):
kwargs={'pk': results['agendas']['all'][0].pk},
)
)
- if (a_count, ct_count, pc_count, pm_count) == (0, 1, 0, 0):
+ if (a_count, ct_count, pc_count, pm_count, p_count) == (0, 1, 0, 0, 0):
# only one check type group imported, redirect to check type page
return HttpResponseRedirect(reverse('lingo-manager-check-type-list'))
- if (a_count, ct_count, pc_count, pm_count) == (0, 0, 1, 0):
+ if (a_count, ct_count, pc_count, pm_count, p_count) == (0, 0, 1, 0, 0):
# 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):
+ if (a_count, ct_count, pc_count, pm_count, p_count) == (0, 0, 0, 1, 0):
# only one pricing model imported, redirect to pricing model page
return HttpResponseRedirect(
reverse(
@@ -222,6 +226,14 @@ class ConfigImportView(FormView):
kwargs={'pk': results['pricing_models']['all'][0].pk},
)
)
+ if (a_count, ct_count, pc_count, pm_count, p_count) == (0, 0, 0, 0, 1):
+ # only one pricing imported, redirect to pricing model page
+ return HttpResponseRedirect(
+ reverse(
+ 'lingo-manager-agenda-pricing-detail',
+ kwargs={'pk': results['pricings']['all'][0].pk},
+ )
+ )
if global_noop:
messages.info(self.request, _('No data found.'))
@@ -343,7 +355,7 @@ class PricingExport(DetailView):
def get(self, request, *args, **kwargs):
response = HttpResponse(content_type='application/json')
today = datetime.date.today()
- attachment = 'attachment; filename="export_pricing_{}_{}.json"'.format(
+ attachment = 'attachment; filename="export_pricing_model_{}_{}.json"'.format(
self.get_object().slug, today.strftime('%Y%m%d')
)
response['Content-Disposition'] = attachment
@@ -786,6 +798,23 @@ class AgendaPricingDeleteView(DeleteView):
agenda_pricing_delete = AgendaPricingDeleteView.as_view()
+class AgendaPricingExport(DetailView):
+ model = AgendaPricing
+
+ def get(self, request, *args, **kwargs):
+ response = HttpResponse(content_type='application/json')
+ today = datetime.date.today()
+ attachment = 'attachment; filename="export_pricing_{}_{}.json"'.format(
+ self.get_object().pricing.slug, today.strftime('%Y%m%d')
+ )
+ response['Content-Disposition'] = attachment
+ json.dump({'pricings': [self.get_object().export_json()]}, response, indent=2)
+ return response
+
+
+agenda_pricing_export = AgendaPricingExport.as_view()
+
+
class AgendaPricingMatrixEdit(FormView):
template_name = 'lingo/pricing/manager_agenda_pricing_matrix_form.html'
diff --git a/tests/pricing/manager/test_import_export.py b/tests/pricing/manager/test_import_export.py
index 869254a..57c78de 100644
--- a/tests/pricing/manager/test_import_export.py
+++ b/tests/pricing/manager/test_import_export.py
@@ -1,11 +1,12 @@
import copy
+import datetime
import json
import pytest
from webtest import Upload
from lingo.agendas.models import Agenda, CheckType, CheckTypeGroup
-from lingo.pricing.models import Criteria, CriteriaCategory, Pricing
+from lingo.pricing.models import AgendaPricing, Criteria, CriteriaCategory, Pricing
from tests.utils import login
pytestmark = pytest.mark.django_db
@@ -55,12 +56,14 @@ def test_export_site(freezer, app, admin_user):
@pytest.mark.freeze_time('2021-07-08')
def test_import_pricing(app, admin_user):
- pricing = Pricing.objects.create(label='Model')
+ pricing = Pricing.objects.create(label='Foo')
app = login(app)
resp = app.get('/manage/pricing/model/%s/export/' % pricing.pk)
assert resp.headers['content-type'] == 'application/json'
- assert resp.headers['content-disposition'] == 'attachment; filename="export_pricing_model_20210708.json"'
+ assert (
+ resp.headers['content-disposition'] == 'attachment; filename="export_pricing_model_foo_20210708.json"'
+ )
pricing_export = resp.text
# existing pricing
@@ -306,3 +309,75 @@ def test_import_check_type_group(app, admin_user):
assert '3 check type groups have been created. No check type group updated.' in resp.text
assert CheckTypeGroup.objects.count() == 3
assert CheckType.objects.count() == 6
+
+
+@pytest.mark.freeze_time('2021-07-08')
+def test_import_agenda_pricing(app, admin_user):
+ pricing = Pricing.objects.create(label='Foo')
+ agenda_pricing = AgendaPricing.objects.create(
+ pricing=pricing,
+ date_start=datetime.date(year=2021, month=9, day=1),
+ date_end=datetime.date(year=2022, month=9, day=1),
+ )
+
+ app = login(app)
+ resp = app.get('/manage/pricing/agenda-pricing/%s/export/' % agenda_pricing.pk)
+ assert resp.headers['content-type'] == 'application/json'
+ assert resp.headers['content-disposition'] == 'attachment; filename="export_pricing_foo_20210708.json"'
+ agenda_pricing_export = resp.text
+
+ # existing agenda_pricing
+ resp = app.get('/manage/pricing/', status=200)
+ resp = resp.click('Import')
+ resp.form['config_json'] = Upload(
+ 'export.json', agenda_pricing_export.encode('utf-8'), 'application/json'
+ )
+ resp = resp.form.submit()
+ assert resp.location.endswith('/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk)
+ resp = resp.follow()
+ assert 'No pricing created. A pricing has been updated.' not in resp.text
+ assert AgendaPricing.objects.count() == 1
+
+ # new agenda_pricing
+ AgendaPricing.objects.all().delete()
+ resp = app.get('/manage/pricing/', status=200)
+ resp = resp.click('Import')
+ resp.form['config_json'] = Upload(
+ 'export.json', agenda_pricing_export.encode('utf-8'), 'application/json'
+ )
+ resp = resp.form.submit()
+ agenda_pricing = AgendaPricing.objects.latest('pk')
+ assert resp.location.endswith('/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk)
+ resp = resp.follow()
+ assert 'A pricing has been created. No pricing updated.' not in resp.text
+ assert AgendaPricing.objects.count() == 1
+
+ # multiple agenda_pricing
+ agenda_pricings = json.loads(agenda_pricing_export)
+ agenda_pricings['pricings'].append(copy.copy(agenda_pricings['pricings'][0]))
+ agenda_pricings['pricings'].append(copy.copy(agenda_pricings['pricings'][0]))
+ agenda_pricings['pricings'][1]['label'] = 'Foo bar 2'
+ agenda_pricings['pricings'][1]['slug'] = 'foo-bar-2'
+ agenda_pricings['pricings'][2]['label'] = 'Foo bar 3'
+ agenda_pricings['pricings'][2]['slug'] = 'foo-bar-3'
+
+ resp = app.get('/manage/pricing/', status=200)
+ resp = resp.click('Import')
+ resp.form['config_json'] = Upload(
+ 'export.json', json.dumps(agenda_pricings).encode('utf-8'), 'application/json'
+ )
+ resp = resp.form.submit()
+ assert resp.location.endswith('/manage/pricing/')
+ resp = resp.follow()
+ assert '2 pricings have been created. A pricing has been updated.' in resp.text
+ assert AgendaPricing.objects.count() == 3
+
+ AgendaPricing.objects.all().delete()
+ resp = app.get('/manage/pricing/', status=200)
+ resp = resp.click('Import')
+ resp.form['config_json'] = Upload(
+ 'export.json', json.dumps(agenda_pricings).encode('utf-8'), 'application/json'
+ )
+ resp = resp.form.submit().follow()
+ assert '3 pricings have been created. No pricing updated.' in resp.text
+ assert AgendaPricing.objects.count() == 3