From b308ddb2405d6042c77174b281bd7ef3d05c2778 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laur=C3=A9line=20Gu=C3=A9rin?= Date: Fri, 13 May 2022 11:17:18 +0200 Subject: [PATCH] pricing: edit pricing_data (#65053) --- chrono/manager/urls.py | 2 +- chrono/pricing/forms.py | 8 + .../manager_agenda_pricing_detail.html | 5 + .../manager_agenda_pricing_matrix_form.html | 58 +++ chrono/pricing/urls.py | 10 + chrono/pricing/views.py | 84 ++++ tests/pricing/test_manager.py | 413 ++++++++++++++++++ 7 files changed, 579 insertions(+), 1 deletion(-) create mode 100644 chrono/pricing/templates/chrono/pricing/manager_agenda_pricing_matrix_form.html diff --git a/chrono/manager/urls.py b/chrono/manager/urls.py index ad1da7db..24dff30e 100644 --- a/chrono/manager/urls.py +++ b/chrono/manager/urls.py @@ -132,7 +132,7 @@ urlpatterns = [ url(r'^agendas/import/$', views.agendas_import, name='chrono-manager-agendas-import'), url(r'^agendas/export/$', views.agendas_export, name='chrono-manager-agendas-export'), url(r'^agendas/(?P\d+)/$', views.agenda_view, name='chrono-manager-agenda-view'), - url(r'^agendas/(?P[-_a-zA-Z]+)/$', views.agenda_view, name='chrono-manager-agenda-view'), + url(r'^agendas/(?P[-_a-zA-Z0-9]+)/$', views.agenda_view, name='chrono-manager-agenda-view'), url( r'^agendas/(?P\d+)/month/$', views.agenda_month_redirect_view, diff --git a/chrono/pricing/forms.py b/chrono/pricing/forms.py index a42d2d73..0d439e76 100644 --- a/chrono/pricing/forms.py +++ b/chrono/pricing/forms.py @@ -114,3 +114,11 @@ class AgendaPricingForm(forms.ModelForm): raise forms.ValidationError(_('Pricing overlaps existing pricings.')) return cleaned_data + + +class PricingMatrixForm(forms.Form): + def __init__(self, *args, **kwargs): + matrix = kwargs.pop('matrix') + super().__init__(*args, **kwargs) + for i in range(len(matrix.rows[0].cells)): + self.fields['crit_%i' % i] = forms.DecimalField(required=True, max_digits=5, decimal_places=2) 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 b27f04f7..586571b5 100644 --- a/chrono/pricing/templates/chrono/pricing/manager_agenda_pricing_detail.html +++ b/chrono/pricing/templates/chrono/pricing/manager_agenda_pricing_detail.html @@ -44,6 +44,11 @@ {% endfor %} + {% if user_can_manage %} +

+ {% trans "Edit Pricing" %} +

+ {% endif %} {% empty %} diff --git a/chrono/pricing/templates/chrono/pricing/manager_agenda_pricing_matrix_form.html b/chrono/pricing/templates/chrono/pricing/manager_agenda_pricing_matrix_form.html new file mode 100644 index 00000000..76397f30 --- /dev/null +++ b/chrono/pricing/templates/chrono/pricing/manager_agenda_pricing_matrix_form.html @@ -0,0 +1,58 @@ +{% extends "chrono/pricing/manager_agenda_pricing_detail.html" %} +{% load i18n chrono %} + +{% block breadcrumb %} +{{ block.super }} +{% if matrix.criteria %} +{% trans "Edit pricing" %} +{% else %} +{% trans "Edit pricing" %} +{% endif %} +{% endblock %} + +{% block appbar %} +

{% trans "Edit pricing" %}

+{% endblock %} + +{% block content %} +
+ {% if matrix.criteria %}

{{ matrix.criteria.label }}

{% endif %} +
+
+ {% csrf_token %} + {{ form.management_form }} + + {% if matrix.rows.0.cells.0.criteria %} + + + + {% for cell in matrix.rows.0.cells %} + + {% endfor %} + + + {% endif %} + + {% for sub_form in form %} + {% with row=matrix.rows|get:forloop.counter0 %} + + + {% for field in sub_form %} + + {% endfor %} + + {% endwith %} + {% endfor %} + +
{{ cell.criteria.label }}
{{ row.criteria.label }} + {{ field.errors.as_ul }} + {{ field }} +
+
+ + {% trans 'Cancel' %} +
+
+
+
+{% endblock %} diff --git a/chrono/pricing/urls.py b/chrono/pricing/urls.py index 5a5cfd69..c95b9e61 100644 --- a/chrono/pricing/urls.py +++ b/chrono/pricing/urls.py @@ -131,4 +131,14 @@ urlpatterns = [ views.agenda_pricing_delete, name='chrono-manager-agenda-pricing-delete', ), + url( + r'^agenda/(?P\d+)/pricing/(?P\d+)/matrix/edit/$', + views.agenda_pricing_matrix_edit, + name='chrono-manager-agenda-pricing-matrix-edit', + ), + url( + r'^agenda/(?P\d+)/pricing/(?P\d+)/matrix/(?P[-_a-zA-Z0-9]+)/edit/$', + views.agenda_pricing_matrix_edit, + name='chrono-manager-agenda-pricing-matrix-slug-edit', + ), ] diff --git a/chrono/pricing/views.py b/chrono/pricing/views.py index 79cf53fe..04c6fe92 100644 --- a/chrono/pricing/views.py +++ b/chrono/pricing/views.py @@ -16,8 +16,10 @@ import datetime import json +from collections import defaultdict from operator import itemgetter +from django import forms from django.core.exceptions import PermissionDenied from django.db.models import Prefetch from django.http import Http404, HttpResponse, HttpResponseBadRequest, HttpResponseRedirect @@ -33,6 +35,7 @@ from chrono.pricing.forms import ( NewCriteriaForm, PricingCriteriaCategoryAddForm, PricingCriteriaCategoryEditForm, + PricingMatrixForm, PricingVariableFormSet, ) from chrono.pricing.models import AgendaPricing, Criteria, CriteriaCategory, Pricing, PricingCriteriaCategory @@ -557,3 +560,84 @@ class AgendaPricingDeleteView(ManagedAgendaMixin, DeleteView): agenda_pricing_delete = AgendaPricingDeleteView.as_view() + + +class AgendaPricingMatrixEdit(ManagedAgendaMixin, FormView): + template_name = 'chrono/pricing/manager_agenda_pricing_matrix_form.html' + + def set_agenda(self, **kwargs): + self.agenda = get_object_or_404(Agenda, pk=kwargs.get('pk'), kind='events') + self.object = get_object_or_404( + AgendaPricing.objects.filter(agenda=self.agenda), pk=kwargs['pricing_pk'] + ) + matrix_list = list(self.object.iter_pricing_matrix()) + if not matrix_list: + raise Http404 + self.matrix = None + if kwargs.get('slug'): + for matrix in matrix_list: + if matrix.criteria is None: + continue + if matrix.criteria.slug == kwargs['slug']: + self.matrix = matrix + break + else: + if matrix_list[0].criteria is None: + self.matrix = matrix_list[0] + if self.matrix is None: + raise Http404 + + def get_context_data(self, **kwargs): + kwargs['object'] = self.object + kwargs['matrix'] = self.matrix + return super().get_context_data(**kwargs) + + def get_form(self): + count = len(self.matrix.rows) + PricingMatrixFormSet = forms.formset_factory( + PricingMatrixForm, min_num=count, max_num=count, extra=0, can_delete=False + ) + kwargs = { + 'initial': [ + {'crit_%i' % i: cell.value for i, cell in enumerate(row.cells)} for row in self.matrix.rows + ] + } + if self.request.method == 'POST': + kwargs.update( + { + 'data': self.request.POST, + } + ) + return PricingMatrixFormSet(form_kwargs={'matrix': self.matrix}, **kwargs) + + def post(self, *args, **kwargs): + form = self.get_form() + if form.is_valid(): + # build prixing_data for this matrix + matrix_pricing_data = defaultdict(dict) + for i, sub_data in enumerate(form.cleaned_data): + row = self.matrix.rows[i] + for j, cell in enumerate(row.cells): + value = sub_data['crit_%s' % j] + key = cell.criteria.identifier if cell.criteria else None + matrix_pricing_data[key][row.criteria.identifier] = float(value) + if self.matrix.criteria: + # full pricing model with 3 categories + self.object.pricing_data = self.object.pricing_data or {} + self.object.pricing_data[self.matrix.criteria.identifier] = matrix_pricing_data + elif list(matrix_pricing_data.keys()) == [None]: + # only one category + self.object.pricing_data = matrix_pricing_data[None] + else: + # 2 categories + self.object.pricing_data = matrix_pricing_data + self.object.save() + return self.form_valid(form) + else: + return self.form_invalid(form) + + def get_success_url(self): + return reverse('chrono-manager-agenda-pricing-detail', args=[self.agenda.pk, self.object.pk]) + + +agenda_pricing_matrix_edit = AgendaPricingMatrixEdit.as_view() diff --git a/tests/pricing/test_manager.py b/tests/pricing/test_manager.py index b6a0ebf9..ae98fe32 100644 --- a/tests/pricing/test_manager.py +++ b/tests/pricing/test_manager.py @@ -1185,3 +1185,416 @@ def test_detail_agenda_pricing_1_category(app, admin_user): 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' + + +def test_edit_agenda_pricing_matrix_3_categories(app, admin_user): + category1 = CriteriaCategory.objects.create(label='Cat 1') + criteria11 = Criteria.objects.create(label='Crit 1-1', slug='crit-1-1', category=category1, order=1) + criteria12 = Criteria.objects.create(label='Crit 1-2', slug='crit-1-2', category=category1, order=2) + category2 = CriteriaCategory.objects.create(label='Cat 2') + criteria21 = 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') + criteria31 = 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)) + resp = resp.click( + href='/manage/pricing/agenda/%s/pricing/%s/matrix/%s/edit/' + % (agenda.pk, agenda_pricing.pk, criteria11.slug) + ) + assert resp.form['form-0-crit_0'].value == '111' + assert resp.form['form-0-crit_1'].value == '' + assert resp.form['form-0-crit_2'].value == '' + assert resp.form['form-1-crit_0'].value == '' + assert resp.form['form-1-crit_1'].value == '' + assert resp.form['form-1-crit_2'].value == '132' + assert resp.form['form-2-crit_0'].value == '' + assert resp.form['form-2-crit_1'].value == '' + assert resp.form['form-2-crit_2'].value == '' + assert resp.form['form-3-crit_0'].value == '114' + assert resp.form['form-3-crit_1'].value == '' + assert resp.form['form-3-crit_2'].value == '' + resp.form['form-0-crit_1'] = '121' + resp.form['form-0-crit_2'] = '131' + resp.form['form-1-crit_0'] = '112' + resp.form['form-1-crit_1'] = '122' + resp.form['form-1-crit_2'] = '132.5' + resp.form['form-2-crit_0'] = '113' + resp.form['form-2-crit_1'] = '123' + resp.form['form-2-crit_2'] = '133' + resp.form['form-3-crit_0'] = '914' + resp.form['form-3-crit_1'] = '124' + resp.form['form-3-crit_2'] = '134' + resp = resp.form.submit() + assert resp.location.endswith('/manage/pricing/agenda/%s/pricing/%s/' % (agenda.pk, agenda_pricing.pk)) + agenda_pricing.refresh_from_db() + assert agenda_pricing.pricing_data == { + 'cat-1:crit-1-1': { + 'cat-2:crit-2-1': { + 'cat-3:crit-3-1': 111, + 'cat-3:crit-3-2': 112, + 'cat-3:crit-3-3': 113, + 'cat-3:crit-3-4': 914, + }, + 'cat-2:crit-2-2': { + 'cat-3:crit-3-1': 121, + 'cat-3:crit-3-2': 122, + 'cat-3:crit-3-3': 123, + 'cat-3:crit-3-4': 124, + }, + 'cat-2:crit-2-3': { + 'cat-3:crit-3-1': 131, + 'cat-3:crit-3-2': 132.5, + 'cat-3:crit-3-3': 133, + 'cat-3:crit-3-4': 134, + }, + }, + 'cat-1:crit-1-2': { + 'cat-2:crit-2-2': { + 'cat-3:crit-3-3': 223, + }, + }, + } + app.get( + '/manage/pricing/agenda/%s/pricing/%s/matrix/%s/edit/' + % (agenda.pk, agenda_pricing.pk, criteria12.slug), + status=200, + ) + + agenda2 = Agenda.objects.create(label='Foo Bar') + agenda_pricing2 = AgendaPricing.objects.create( + agenda=agenda2, + pricing=pricing, + date_start=datetime.date(year=2021, month=9, day=1), + date_end=datetime.date(year=2022, month=9, day=1), + ) + app.get( + '/manage/pricing/agenda/%s/pricing/%s/matrix/%s/edit/' + % (agenda.pk, agenda_pricing2.pk, criteria11.slug), + status=404, + ) + app.get( + '/manage/pricing/agenda/%s/pricing/%s/matrix/%s/edit/' % (0, agenda_pricing.pk, criteria11.slug), + status=404, + ) + app.get( + '/manage/pricing/agenda/%s/pricing/%s/matrix/%s/edit/' % (agenda.pk, 0, criteria11.slug), status=404 + ) + app.get( + '/manage/pricing/agenda/%s/pricing/%s/matrix/%s/edit/' % (agenda.pk, agenda_pricing.pk, 'unknown'), + status=404, + ) + app.get( + '/manage/pricing/agenda/%s/pricing/%s/matrix/%s/edit/' + % (agenda.pk, agenda_pricing.pk, criteria21.slug), + status=404, + ) + app.get( + '/manage/pricing/agenda/%s/pricing/%s/matrix/%s/edit/' + % (agenda.pk, agenda_pricing.pk, criteria31.slug), + status=404, + ) + app.get('/manage/pricing/agenda/%s/pricing/%s/matrix/edit/' % (agenda.pk, agenda_pricing.pk), status=404) + # wrong kind + for kind in ['meetings', 'virtual']: + agenda.kind = kind + agenda.save() + app.get( + '/manage/pricing/agenda/%s/pricing/%s/matrix/%s/edit/' + % (agenda.pk, agenda_pricing.pk, criteria11.slug), + status=404, + ) + + +def test_edit_agenda_pricing_matrix_2_categories(app, admin_user): + category2 = CriteriaCategory.objects.create(label='Cat 2') + criteria21 = 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') + criteria31 = 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)) + resp = resp.click( + href='/manage/pricing/agenda/%s/pricing/%s/matrix/edit/' % (agenda.pk, agenda_pricing.pk) + ) + assert resp.form['form-0-crit_0'].value == '111' + assert resp.form['form-0-crit_1'].value == '' + assert resp.form['form-0-crit_2'].value == '' + assert resp.form['form-1-crit_0'].value == '' + assert resp.form['form-1-crit_1'].value == '' + assert resp.form['form-1-crit_2'].value == '132' + assert resp.form['form-2-crit_0'].value == '' + assert resp.form['form-2-crit_1'].value == '' + assert resp.form['form-2-crit_2'].value == '' + assert resp.form['form-3-crit_0'].value == '114' + assert resp.form['form-3-crit_1'].value == '' + assert resp.form['form-3-crit_2'].value == '' + resp.form['form-0-crit_1'] = '121' + resp.form['form-0-crit_2'] = '131' + resp.form['form-1-crit_0'] = '112' + resp.form['form-1-crit_1'] = '122' + resp.form['form-1-crit_2'] = '132.5' + resp.form['form-2-crit_0'] = '113' + resp.form['form-2-crit_1'] = '123' + resp.form['form-2-crit_2'] = '133' + resp.form['form-3-crit_0'] = '914' + resp.form['form-3-crit_1'] = '124' + resp.form['form-3-crit_2'] = '134' + resp = resp.form.submit() + assert resp.location.endswith('/manage/pricing/agenda/%s/pricing/%s/' % (agenda.pk, agenda_pricing.pk)) + agenda_pricing.refresh_from_db() + assert agenda_pricing.pricing_data == { + 'cat-2:crit-2-1': { + 'cat-3:crit-3-1': 111, + 'cat-3:crit-3-2': 112, + 'cat-3:crit-3-3': 113, + 'cat-3:crit-3-4': 914, + }, + 'cat-2:crit-2-2': { + 'cat-3:crit-3-1': 121, + 'cat-3:crit-3-2': 122, + 'cat-3:crit-3-3': 123, + 'cat-3:crit-3-4': 124, + }, + 'cat-2:crit-2-3': { + 'cat-3:crit-3-1': 131, + 'cat-3:crit-3-2': 132.5, + 'cat-3:crit-3-3': 133, + 'cat-3:crit-3-4': 134, + }, + } + + agenda2 = Agenda.objects.create(label='Foo Bar') + agenda_pricing2 = AgendaPricing.objects.create( + agenda=agenda2, + pricing=pricing, + date_start=datetime.date(year=2021, month=9, day=1), + date_end=datetime.date(year=2022, month=9, day=1), + ) + app.get('/manage/pricing/agenda/%s/pricing/%s/matrix/edit/' % (agenda.pk, agenda_pricing2.pk), status=404) + app.get('/manage/pricing/agenda/%s/pricing/%s/matrix/edit/' % (0, agenda_pricing.pk), status=404) + app.get('/manage/pricing/agenda/%s/pricing/%s/matrix/edit/' % (agenda.pk, 0), status=404) + app.get( + '/manage/pricing/agenda/%s/pricing/%s/matrix/%s/edit/' + % (agenda.pk, agenda_pricing.pk, criteria21.slug), + status=404, + ) + app.get( + '/manage/pricing/agenda/%s/pricing/%s/matrix/%s/edit/' + % (agenda.pk, agenda_pricing.pk, criteria31.slug), + status=404, + ) + # wrong kind + for kind in ['meetings', 'virtual']: + agenda.kind = kind + agenda.save() + app.get( + '/manage/pricing/agenda/%s/pricing/%s/matrix/edit/' % (agenda.pk, agenda_pricing.pk), status=404 + ) + + +def test_edit_agenda_pricing_matrix_1_category(app, admin_user): + category3 = CriteriaCategory.objects.create(label='Cat 3') + criteria31 = 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)) + resp = resp.click( + href='/manage/pricing/agenda/%s/pricing/%s/matrix/edit/' % (agenda.pk, agenda_pricing.pk) + ) + assert resp.form['form-0-crit_0'].value == '111' + assert resp.form['form-1-crit_0'].value == '' + assert resp.form['form-2-crit_0'].value == '' + assert resp.form['form-3-crit_0'].value == '114' + resp.form['form-1-crit_0'] = '112.5' + resp.form['form-2-crit_0'] = '113' + resp.form['form-3-crit_0'] = '914' + resp = resp.form.submit() + assert resp.location.endswith('/manage/pricing/agenda/%s/pricing/%s/' % (agenda.pk, agenda_pricing.pk)) + agenda_pricing.refresh_from_db() + assert agenda_pricing.pricing_data == { + 'cat-3:crit-3-1': 111, + 'cat-3:crit-3-2': 112.5, + 'cat-3:crit-3-3': 113, + 'cat-3:crit-3-4': 914, + } + + agenda2 = Agenda.objects.create(label='Foo Bar') + agenda_pricing2 = AgendaPricing.objects.create( + agenda=agenda2, + pricing=pricing, + date_start=datetime.date(year=2021, month=9, day=1), + date_end=datetime.date(year=2022, month=9, day=1), + ) + app.get('/manage/pricing/agenda/%s/pricing/%s/matrix/edit/' % (agenda.pk, agenda_pricing2.pk), status=404) + app.get('/manage/pricing/agenda/%s/pricing/%s/matrix/edit/' % (0, agenda_pricing.pk), status=404) + app.get('/manage/pricing/agenda/%s/pricing/%s/matrix/edit/' % (agenda.pk, 0), status=404) + app.get( + '/manage/pricing/agenda/%s/pricing/%s/matrix/%s/edit/' + % (agenda.pk, agenda_pricing.pk, criteria31.slug), + status=404, + ) + # wrong kind + for kind in ['meetings', 'virtual']: + agenda.kind = kind + agenda.save() + app.get( + '/manage/pricing/agenda/%s/pricing/%s/matrix/edit/' % (agenda.pk, agenda_pricing.pk), status=404 + ) + + +def test_edit_agenda_pricing_matrix_empty(app, admin_user): + agenda = Agenda.objects.create(label='Foo bar', kind='events') + pricing = Pricing.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), + ) + + app = login(app) + app.get('/manage/pricing/agenda/%s/pricing/%s/matrix/edit/' % (agenda.pk, agenda_pricing.pk), status=404) + + +def test_edit_agenda_pricing_matrix_as_manager(app, manager_user, agenda_with_restrictions): + 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') + category3 = CriteriaCategory.objects.create(label='Cat 3') + pricing = Pricing.objects.create(label='Model') + agenda_pricing = AgendaPricing.objects.create( + agenda=agenda_with_restrictions, + pricing=pricing, + date_start=datetime.date(year=2021, month=9, day=1), + date_end=datetime.date(year=2021, month=10, day=1), + ) + pricing.categories.add(category1, through_defaults={'order': 1}) + pricing.criterias.set(Criteria.objects.all()) + + def check(): + resp = app.get( + '/manage/pricing/agenda/%s/pricing/%s/' % (agenda_with_restrictions.pk, agenda_pricing.pk) + ) + assert ( + '/manage/pricing/agenda/%s/pricing/%s/matrix/edit/' + % (agenda_with_restrictions.pk, agenda_pricing.pk) + not in resp + ) + for slug in ['crit-1-1', 'crit-1-2']: + assert ( + '/manage/pricing/agenda/%s/pricing/%s/matrix/%s/edit/' + % (agenda_with_restrictions.pk, agenda_pricing.pk, slug) + not in resp + ) + + app = login(app, username='manager', password='manager') + app.get( + '/manage/pricing/agenda/%s/pricing/%s/matrix/edit/' + % (agenda_with_restrictions.pk, agenda_pricing.pk), + status=403, + ) + check() + + pricing.categories.add(category2, through_defaults={'order': 2}) + app.get( + '/manage/pricing/agenda/%s/pricing/%s/matrix/edit/' + % (agenda_with_restrictions.pk, agenda_pricing.pk), + status=403, + ) + check() + + pricing.categories.add(category3, through_defaults={'order': 3}) + app.get( + '/manage/pricing/agenda/%s/pricing/%s/matrix/crit-1-1/edit/' + % (agenda_with_restrictions.pk, agenda_pricing.pk), + status=403, + ) + app.get( + '/manage/pricing/agenda/%s/pricing/%s/matrix/crit-1-2/edit/' + % (agenda_with_restrictions.pk, agenda_pricing.pk), + status=403, + ) + check()