diff --git a/chrono/pricing/templates/chrono/pricing/manager_agenda_pricing_detail.html b/chrono/pricing/templates/chrono/pricing/manager_agenda_pricing_detail.html index c2d9450d..b27f04f7 100644 --- a/chrono/pricing/templates/chrono/pricing/manager_agenda_pricing_detail.html +++ b/chrono/pricing/templates/chrono/pricing/manager_agenda_pricing_detail.html @@ -22,4 +22,35 @@ {% endblock %} {% block content %} +{% for matrix in object.iter_pricing_matrix %} +
+ {% if matrix.criteria %}

{{ matrix.criteria.label }}

{% endif %} +
+ + {% if matrix.rows.0.cells.0.criteria %} + + + + {% for cell in matrix.rows.0.cells %}{% endfor %} + + + {% endif %} + + {% for row in matrix.rows %} + + + {% for cell in row.cells %}{% endfor %} + + {% endfor %} + +
{{ cell.criteria.label }}
{{ row.criteria.label }}{{ cell.value|floatformat:"2"|default_if_none:"" }}
+
+
+{% empty %} +
+ {% blocktrans %} + This pricing model is misconfigured. + {% endblocktrans %} +
+{% endfor %} {% endblock %} diff --git a/chrono/pricing/views.py b/chrono/pricing/views.py index 2bc593c8..79cf53fe 100644 --- a/chrono/pricing/views.py +++ b/chrono/pricing/views.py @@ -513,7 +513,9 @@ class AgendaPricingDetailView(ViewableAgendaMixin, DetailView): self.agenda = get_object_or_404(Agenda, pk=kwargs.get('pk'), kind='events') def get_queryset(self): - return AgendaPricing.objects.filter(agenda=self.agenda) + return AgendaPricing.objects.filter(agenda=self.agenda).prefetch_related( + 'pricing__criterias__category' + ) def get_context_data(self, **kwargs): kwargs['user_can_manage'] = self.agenda.can_be_managed(self.request.user) diff --git a/tests/pricing/test_manager.py b/tests/pricing/test_manager.py index a472e35e..b6a0ebf9 100644 --- a/tests/pricing/test_manager.py +++ b/tests/pricing/test_manager.py @@ -978,3 +978,210 @@ def test_detail_agenda_pricing(app, admin_user): agenda.kind = kind agenda.save() app.get('/manage/pricing/agenda/%s/pricing/%s/' % (agenda.pk, agenda_pricing.pk), status=404) + + +def test_detail_agenda_pricing_3_categories(app, admin_user): + category1 = CriteriaCategory.objects.create(label='Cat 1') + Criteria.objects.create(label='Crit 1-1', slug='crit-1-1', category=category1, order=1) + Criteria.objects.create(label='Crit 1-2', slug='crit-1-2', category=category1, order=2) + category2 = CriteriaCategory.objects.create(label='Cat 2') + Criteria.objects.create(label='Crit 2-1', slug='crit-2-1', category=category2, order=1) + Criteria.objects.create(label='Crit 2-2', slug='crit-2-2', category=category2, order=2) + Criteria.objects.create(label='Crit 2-3', slug='crit-2-3', category=category2, order=3) + category3 = CriteriaCategory.objects.create(label='Cat 3') + Criteria.objects.create(label='Crit 3-1', slug='crit-3-1', category=category3, order=1) + Criteria.objects.create(label='Crit 3-3', slug='crit-3-3', category=category3, order=3) + Criteria.objects.create(label='Crit 3-4', slug='crit-3-4', category=category3, order=4) + Criteria.objects.create(label='Crit 3-2', slug='crit-3-2', category=category3, order=2) + + agenda = Agenda.objects.create(label='Foo bar', kind='events') + pricing = Pricing.objects.create(label='Foo bar') + pricing.categories.add(category1, through_defaults={'order': 1}) + pricing.categories.add(category2, through_defaults={'order': 2}) + pricing.categories.add(category3, through_defaults={'order': 3}) + pricing.criterias.set(Criteria.objects.all()) + 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={ + 'cat-1:crit-1-1': { + 'cat-2:crit-2-1': { + 'cat-3:crit-3-1': 111, + 'cat-3:crit-3-3': 'not-a-decimal', + 'cat-3:crit-3-4': 114, + }, + 'cat-2:crit-2-3': { + 'cat-3:crit-3-2': 132, + }, + }, + 'cat-1:crit-1-2': { + 'cat-2:crit-2-2': { + 'cat-3:crit-3-3': 223, + }, + }, + }, + ) + + app = login(app) + resp = app.get('/manage/pricing/agenda/%s/pricing/%s/' % (agenda.pk, agenda_pricing.pk)) + assert '

Crit 1-1

' in resp + ths = resp.pyquery.find('table.pricing-matrix-crit-1-1 thead th') + assert len(ths) == 4 + assert ths[0].text is None + assert ths[1].text == 'Crit 2-1' + assert ths[2].text == 'Crit 2-2' + assert ths[3].text == 'Crit 2-3' + assert resp.pyquery.find('table.pricing-matrix-crit-1-1 tr.pricing-row-crit-3-1 th')[0].text == 'Crit 3-1' + assert resp.pyquery.find('table.pricing-matrix-crit-1-1 tr.pricing-row-crit-3-2 th')[0].text == 'Crit 3-2' + assert resp.pyquery.find('table.pricing-matrix-crit-1-1 tr.pricing-row-crit-3-3 th')[0].text == 'Crit 3-3' + assert resp.pyquery.find('table.pricing-matrix-crit-1-1 tr.pricing-row-crit-3-4 th')[0].text == 'Crit 3-4' + assert ( + resp.pyquery.find('table.pricing-matrix-crit-1-1 tr.pricing-row-crit-3-1 td.pricing-cell-crit-2-1')[ + 0 + ].text + == '111.00' + ) + assert ( + resp.pyquery.find('table.pricing-matrix-crit-1-1 tr.pricing-row-crit-3-2 td.pricing-cell-crit-2-1')[ + 0 + ].text + is None + ) # not defined + assert ( + resp.pyquery.find('table.pricing-matrix-crit-1-1 tr.pricing-row-crit-3-3 td.pricing-cell-crit-2-1')[ + 0 + ].text + is None + ) # wrong value + assert ( + resp.pyquery.find('table.pricing-matrix-crit-1-1 tr.pricing-row-crit-3-4 td.pricing-cell-crit-2-1')[ + 0 + ].text + == '114.00' + ) + assert ( + resp.pyquery.find('table.pricing-matrix-crit-1-1 tr.pricing-row-crit-3-2 td.pricing-cell-crit-2-3')[ + 0 + ].text + == '132.00' + ) + assert '

Crit 1-2

' in resp + ths = resp.pyquery.find('table.pricing-matrix-crit-1-2 thead th') + assert len(ths) == 4 + assert ths[0].text is None + assert ths[1].text == 'Crit 2-1' + assert ths[2].text == 'Crit 2-2' + assert ths[3].text == 'Crit 2-3' + assert resp.pyquery.find('table.pricing-matrix-crit-1-2 tr.pricing-row-crit-3-1 th')[0].text == 'Crit 3-1' + assert resp.pyquery.find('table.pricing-matrix-crit-1-2 tr.pricing-row-crit-3-2 th')[0].text == 'Crit 3-2' + assert resp.pyquery.find('table.pricing-matrix-crit-1-2 tr.pricing-row-crit-3-3 th')[0].text == 'Crit 3-3' + assert resp.pyquery.find('table.pricing-matrix-crit-1-2 tr.pricing-row-crit-3-4 th')[0].text == 'Crit 3-4' + assert ( + resp.pyquery.find('table.pricing-matrix-crit-1-2 tr.pricing-row-crit-3-2 td.pricing-cell-crit-2-2')[ + 0 + ].text + is None + ) # not defined + assert ( + resp.pyquery.find('table.pricing-matrix-crit-1-2 tr.pricing-row-crit-3-3 td.pricing-cell-crit-2-2')[ + 0 + ].text + == '223.00' + ) + + +def test_detail_agenda_pricing_2_categories(app, admin_user): + category2 = CriteriaCategory.objects.create(label='Cat 2') + Criteria.objects.create(label='Crit 2-1', slug='crit-2-1', category=category2, order=1) + Criteria.objects.create(label='Crit 2-2', slug='crit-2-2', category=category2, order=2) + Criteria.objects.create(label='Crit 2-3', slug='crit-2-3', category=category2, order=3) + category3 = CriteriaCategory.objects.create(label='Cat 3') + Criteria.objects.create(label='Crit 3-1', slug='crit-3-1', category=category3, order=1) + Criteria.objects.create(label='Crit 3-3', slug='crit-3-3', category=category3, order=3) + Criteria.objects.create(label='Crit 3-4', slug='crit-3-4', category=category3, order=4) + Criteria.objects.create(label='Crit 3-2', slug='crit-3-2', category=category3, order=2) + + agenda = Agenda.objects.create(label='Foo bar', kind='events') + pricing = Pricing.objects.create(label='Foo bar') + pricing.categories.add(category2, through_defaults={'order': 2}) + pricing.categories.add(category3, through_defaults={'order': 3}) + pricing.criterias.set(Criteria.objects.all()) + 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={ + 'cat-2:crit-2-1': { + 'cat-3:crit-3-1': 111, + 'cat-3:crit-3-3': 'not-a-decimal', + 'cat-3:crit-3-4': 114, + }, + 'cat-2:crit-2-3': { + 'cat-3:crit-3-2': 132, + }, + }, + ) + + app = login(app) + resp = app.get('/manage/pricing/agenda/%s/pricing/%s/' % (agenda.pk, agenda_pricing.pk)) + assert '

' not in resp + ths = resp.pyquery.find('table thead th') + assert len(ths) == 4 + assert ths[0].text is None + assert ths[1].text == 'Crit 2-1' + assert ths[2].text == 'Crit 2-2' + assert ths[3].text == 'Crit 2-3' + assert resp.pyquery.find('table tr.pricing-row-crit-3-1 th')[0].text == 'Crit 3-1' + assert resp.pyquery.find('table tr.pricing-row-crit-3-2 th')[0].text == 'Crit 3-2' + assert resp.pyquery.find('table tr.pricing-row-crit-3-3 th')[0].text == 'Crit 3-3' + assert resp.pyquery.find('table tr.pricing-row-crit-3-4 th')[0].text == 'Crit 3-4' + assert resp.pyquery.find('table tr.pricing-row-crit-3-1 td.pricing-cell-crit-2-1')[0].text == '111.00' + assert ( + resp.pyquery.find('table tr.pricing-row-crit-3-2 td.pricing-cell-crit-2-1')[0].text is None + ) # not defined + assert ( + resp.pyquery.find('table tr.pricing-row-crit-3-3 td.pricing-cell-crit-2-1')[0].text is None + ) # wrong value + assert resp.pyquery.find('table tr.pricing-row-crit-3-4 td.pricing-cell-crit-2-1')[0].text == '114.00' + assert resp.pyquery.find('table tr.pricing-row-crit-3-2 td.pricing-cell-crit-2-3')[0].text == '132.00' + + +def test_detail_agenda_pricing_1_category(app, admin_user): + category3 = CriteriaCategory.objects.create(label='Cat 3') + Criteria.objects.create(label='Crit 3-1', slug='crit-3-1', category=category3, order=1) + Criteria.objects.create(label='Crit 3-3', slug='crit-3-3', category=category3, order=3) + Criteria.objects.create(label='Crit 3-4', slug='crit-3-4', category=category3, order=4) + Criteria.objects.create(label='Crit 3-2', slug='crit-3-2', category=category3, order=2) + + agenda = Agenda.objects.create(label='Foo bar', kind='events') + pricing = Pricing.objects.create(label='Foo bar') + pricing.categories.add(category3, through_defaults={'order': 3}) + pricing.criterias.set(Criteria.objects.all()) + 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={ + 'cat-3:crit-3-1': 111, + 'cat-3:crit-3-3': 'not-a-decimal', + 'cat-3:crit-3-4': 114, + }, + ) + + app = login(app) + resp = app.get('/manage/pricing/agenda/%s/pricing/%s/' % (agenda.pk, agenda_pricing.pk)) + assert '

' not in resp + ths = resp.pyquery.find('table thead') + assert len(ths) == 0 + assert resp.pyquery.find('table tr.pricing-row-crit-3-1 th')[0].text == 'Crit 3-1' + assert resp.pyquery.find('table tr.pricing-row-crit-3-2 th')[0].text == 'Crit 3-2' + assert resp.pyquery.find('table tr.pricing-row-crit-3-3 th')[0].text == 'Crit 3-3' + assert resp.pyquery.find('table tr.pricing-row-crit-3-4 th')[0].text == 'Crit 3-4' + assert resp.pyquery.find('table tr.pricing-row-crit-3-1 td')[0].text == '111.00' + assert resp.pyquery.find('table tr.pricing-row-crit-3-2 td')[0].text is None # not defined + assert resp.pyquery.find('table tr.pricing-row-crit-3-3 td')[0].text is None # wrong value + assert resp.pyquery.find('table tr.pricing-row-crit-3-4 td')[0].text == '114.00'