From 9c9ed8033fb9bff7fac738c696adc18322966f3e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Laur=C3=A9line=20Gu=C3=A9rin?= <zebuline@entrouvert.com>
Date: Tue, 26 Jul 2022 09:26:29 +0200
Subject: [PATCH 04/14] pricing: agendas not linkable if subscription not
 required (#67675)

---
 lingo/pricing/forms.py                        | 10 +++++++
 .../manager_agenda_pricing_detail.html        |  4 +++
 lingo/pricing/views.py                        |  4 +--
 tests/pricing/manager/test_agenda_pricing.py  | 26 +++++++++++++++++++
 4 files changed, 42 insertions(+), 2 deletions(-)

diff --git a/lingo/pricing/forms.py b/lingo/pricing/forms.py
index a7494be..4d7caab 100644
--- a/lingo/pricing/forms.py
+++ b/lingo/pricing/forms.py
@@ -174,6 +174,16 @@ class AgendaPricingForm(NewAgendaPricingForm):
 
         return slug
 
+    def clean_subscription_required(self):
+        subscription_required = self.cleaned_data['subscription_required']
+        if subscription_required is False and self.instance.subscription_required is True:
+            # value has changed, check linked agendas
+            if self.instance.agendas.exists():
+                raise forms.ValidationError(
+                    _('Some agendas are linked to this pricing; please unlink them first.')
+                )
+        return subscription_required
+
 
 class AgendaPricingAgendaAddForm(forms.Form):
     agenda = forms.ModelChoiceField(label=_('Agenda to add'), queryset=Agenda.objects.none(), required=True)
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 f6ba8ad..35bed3d 100644
--- a/lingo/pricing/templates/lingo/pricing/manager_agenda_pricing_detail.html
+++ b/lingo/pricing/templates/lingo/pricing/manager_agenda_pricing_detail.html
@@ -27,7 +27,9 @@
 <div class="pk-tabs">
   <div class="pk-tabs--tab-list" role="tablist">
     <button aria-controls="panel-options" aria-selected="true" id="tab-options" role="tab" tabindex="0">{% trans "Options" %}</button>
+    {% if object.subscription_required %}
     <button aria-controls="panel-agendas" aria-selected="false" id="tab-agendas" role="tab" tabindex="0">{% trans "Agendas" %}</button>
+    {% endif %}
     <button aria-controls="panel-debug" aria-selected="false" id="tab-debug" role="tab" tabindex="0">{% trans "Test tool" %}</button>
     {% for matrix in iter_matrix %}
     <button aria-controls="panel-matrix-{{ matrix.criteria.slug }}" aria-selected="false" id="tab-matrix-{{ matrix.criteria.slug }}" role="tab" tabindex="-1">{% trans "Pricings" context 'amount' %}{% if matrix.criteria %} - {{ matrix.criteria.label }}{% endif %}</button>
@@ -48,6 +50,7 @@
       </ul>
     </div>
 
+    {% if object.subscription_required %}
     <div aria-labelledby="tab-agendas" hidden id="panel-agendas" role="tabpanel" tabindex="0">
       <ul class="objects-list single-links">
         {% for agenda in agendas %}
@@ -63,6 +66,7 @@
         <a class="pk-button" rel="popup" href="{% url 'lingo-manager-agenda-pricing-agenda-add' object.pk %}">{% trans "Add an agenda" %}</a>
       </div>
     </div>
+    {% endif %}
 
     <div aria-labelledby="tab-debug" hidden id="panel-debug" role="tabpanel" tabindex="0">
       <form method="get" enctype="multipart/form-data" action="{% url 'lingo-manager-agenda-pricing-test-tool' object.pk %}">
diff --git a/lingo/pricing/views.py b/lingo/pricing/views.py
index 2b46a3c..eef24ac 100644
--- a/lingo/pricing/views.py
+++ b/lingo/pricing/views.py
@@ -834,7 +834,7 @@ class AgendaPricingAgendaAddView(FormView):
     form_class = AgendaPricingAgendaAddForm
 
     def dispatch(self, request, *args, **kwargs):
-        self.object = get_object_or_404(AgendaPricing, pk=kwargs['pk'])
+        self.object = get_object_or_404(AgendaPricing, pk=kwargs['pk'], subscription_required=True)
         return super().dispatch(request, *args, **kwargs)
 
     def get_form_kwargs(self):
@@ -863,7 +863,7 @@ class AgendaPricingAgendaDeleteView(DeleteView):
     pk_url_kwarg = 'agenda_pk'
 
     def dispatch(self, request, *args, **kwargs):
-        self.agenda_pricing = get_object_or_404(AgendaPricing, pk=kwargs['pk'])
+        self.agenda_pricing = get_object_or_404(AgendaPricing, pk=kwargs['pk'], subscription_required=True)
         return super().dispatch(request, *args, **kwargs)
 
     def get_queryset(self):
diff --git a/tests/pricing/manager/test_agenda_pricing.py b/tests/pricing/manager/test_agenda_pricing.py
index 47cf490..87d178d 100644
--- a/tests/pricing/manager/test_agenda_pricing.py
+++ b/tests/pricing/manager/test_agenda_pricing.py
@@ -108,6 +108,22 @@ def test_edit_agenda_pricing(app, admin_user):
     assert agenda_pricing.flat_fee_schedule is True
     assert agenda_pricing.subscription_required is False
 
+    agenda = Agenda.objects.create(label='Foo bar')
+    agenda_pricing.agendas.add(agenda)
+    agenda_pricing.subscription_required = True
+    agenda_pricing.save()
+    resp = app.get('/manage/pricing/agenda-pricing/%s/edit/' % agenda_pricing.pk)
+    resp.form['subscription_required'] = False
+    resp = resp.form.submit()
+    assert resp.context['form'].errors['subscription_required'] == [
+        'Some agendas are linked to this pricing; please unlink them first.'
+    ]
+    agenda_pricing.subscription_required = False
+    agenda_pricing.save()
+    resp = app.get('/manage/pricing/agenda-pricing/%s/edit/' % agenda_pricing.pk)
+    resp = resp.form.submit()
+    assert resp.location.endswith('/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk)
+
 
 def test_detail_agenda_pricing(app, admin_user):
     pricing = Pricing.objects.create(label='Model')
@@ -196,6 +212,10 @@ def test_agenda_pricing_add_agenda(app, admin_user):
     resp = resp.form.submit().follow()
     assert list(agenda_pricing2.agendas.all()) == [agenda3]
 
+    agenda_pricing.subscription_required = False
+    agenda_pricing.save()
+    app.get('/manage/pricing/agenda-pricing/%s/agenda/add/' % agenda_pricing.pk, status=404)
+
 
 def test_agenda_pricing_delete_agenda(app, admin_user):
     pricing = Pricing.objects.create(label='Model')
@@ -226,6 +246,12 @@ def test_agenda_pricing_delete_agenda(app, admin_user):
     # unknown
     app.get('/manage/pricing/agenda-pricing/%s/agenda/%s/delete/' % (agenda_pricing.pk, 0), status=404)
 
+    agenda_pricing.subscription_required = False
+    agenda_pricing.save()
+    app.get(
+        '/manage/pricing/agenda-pricing/%s/agenda/%s/delete/' % (agenda_pricing.pk, agenda2.pk), status=404
+    )
+
 
 def test_detail_agenda_pricing_3_categories(app, admin_user):
     category1 = CriteriaCategory.objects.create(label='Cat 1')
-- 
2.35.1

