diff --git a/lemarche/templates/tenders/_detail_cta_not_interested.html b/lemarche/templates/tenders/_detail_cta_not_interested.html index 9364110ec..82909cdc1 100644 --- a/lemarche/templates/tenders/_detail_cta_not_interested.html +++ b/lemarche/templates/tenders/_detail_cta_not_interested.html @@ -6,14 +6,29 @@

Pas intéressé ?

Cette demande ne vous intéresse pas ? Dites-le nous !

- {% if user.is_authenticated %} - - {% elif siae_id %} - + {% if user_can_click %} +
+ {% csrf_token %} +
+ + +
+
+ {% if user.is_authenticated %} + + {% elif siae_id %} + + {% endif %} +
+
+ {% else %} + + {{ tender.cta_not_interested_card_button_text|safe }} + {% endif %} diff --git a/lemarche/templates/tenders/detail.html b/lemarche/templates/tenders/detail.html index e8c7ef204..da01f709f 100644 --- a/lemarche/templates/tenders/detail.html +++ b/lemarche/templates/tenders/detail.html @@ -112,7 +112,7 @@ {% elif not siae_has_detail_contact_click_date %} {% include "tenders/_detail_cta.html" with tender=tender user_can_click=True %} {% include "tenders/_detail_cta_cocontracting.html" with tender=tender %} - {% include "tenders/_detail_cta_not_interested.html" with tender=tender %} + {% include "tenders/_detail_cta_not_interested.html" with tender=tender user_can_click=True %} {% endif %} {% endif %} {% comment %} if siae_id {% endcomment %} @@ -133,6 +133,7 @@ {% endif %} {% else %} {% include "tenders/_detail_cta.html" with tender=tender user_can_click=False %} + {% include "tenders/_detail_cta_not_interested.html" with tender=tender user_can_click=False %} {% endif %} {% endif %} {% endif %} diff --git a/lemarche/tenders/migrations/0069_tendersiae_detail_not_interested_feedback.py b/lemarche/tenders/migrations/0069_tendersiae_detail_not_interested_feedback.py new file mode 100644 index 000000000..99b6d20f5 --- /dev/null +++ b/lemarche/tenders/migrations/0069_tendersiae_detail_not_interested_feedback.py @@ -0,0 +1,17 @@ +# Generated by Django 4.2.9 on 2024-01-18 14:41 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("tenders", "0068_tender_siae_detail_cocontracting_and_not_interested_click_count"), + ] + + operations = [ + migrations.AddField( + model_name="tendersiae", + name="detail_not_interested_feedback", + field=models.TextField(blank=True, verbose_name="Clic sur Pas intéréssé : explication"), + ), + ] diff --git a/lemarche/tenders/models.py b/lemarche/tenders/models.py index 3720349d7..fc8090db9 100644 --- a/lemarche/tenders/models.py +++ b/lemarche/tenders/models.py @@ -649,6 +649,10 @@ def cta_card_button_text(self): return "Je suis intéressé !" return "Accéder aux coordonnées" + @property + def cta_not_interested_card_button_text(self): + return "Je ne suis pas intéressé" + @cached_property def can_display_contact_email(self): return (tender_constants.RESPONSE_KIND_EMAIL in self.response_kind) and self.contact_email @@ -823,6 +827,7 @@ class TenderSiae(models.Model): "Date de clic sur Répondre en co-traitance", blank=True, null=True ) detail_not_interested_click_date = models.DateTimeField("Date de clic sur Pas intéressé", blank=True, null=True) + detail_not_interested_feedback = models.TextField(verbose_name="Clic sur Pas intéréssé : explication", blank=True) logs = models.JSONField(verbose_name="Logs historiques", editable=False, default=list) created_at = models.DateTimeField(verbose_name="Date de création", default=timezone.now) diff --git a/lemarche/www/tenders/tests.py b/lemarche/www/tenders/tests.py index de5c3e550..aed0ecbcb 100644 --- a/lemarche/www/tenders/tests.py +++ b/lemarche/www/tenders/tests.py @@ -1235,13 +1235,12 @@ def test_user_can_notify_cocontracting_wish_with_siae_id(self): # missing siae with mock.patch("lemarche.www.tenders.tasks.send_mail_async") as mock_send_mail_async: response = self.client.post(f"{url}?siae_id=999999", data={}) + tendersiae = TenderSiae.objects.get(tender=self.tender, siae=self.siae) self.assertContains( response, "nous n'avons pas pu prendre en compte votre souhait de répondre en co-traitance" ) mock_send_mail_async.assert_not_called() - self.assertEqual( - TenderSiae.objects.get(tender=self.tender, siae=self.siae).detail_cocontracting_click_date, None - ) + self.assertIsNone(tendersiae.detail_cocontracting_click_date) detail_url = reverse("tenders:detail", kwargs={"slug": self.tender.slug}) + f"?siae_id={self.siae.id}" response = self.client.get(detail_url) @@ -1250,13 +1249,12 @@ def test_user_can_notify_cocontracting_wish_with_siae_id(self): with mock.patch("lemarche.www.tenders.tasks.send_mail_async") as mock_send_mail_async: response = self.client.post(f"{url}?siae_id={self.siae.id}", data={}) + tendersiae = TenderSiae.objects.get(tender=self.tender, siae=self.siae) self.assertContains(response, "Votre intérêt a bien été signalé au client.") mock_send_mail_async.assert_called_once() email_body = mock_send_mail_async.call_args[1]["email_body"] self.assertTrue(f"La structure {self.siae.name } souhaite répondre en co-traitance" in email_body) - self.assertNotEqual( - TenderSiae.objects.get(tender=self.tender, siae=self.siae).detail_cocontracting_click_date, None - ) + self.assertIsNotNone(tendersiae.detail_cocontracting_click_date) response = self.client.get(detail_url) self.assertContains(response, "Votre intérêt a bien été signalé au client.") self.assertNotContains(response, "Répondre en co-traitance ?") @@ -1270,18 +1268,16 @@ def test_user_can_notify_cocontracting_wish_with_authenticated_user(self): self.assertNotContains(response, "Votre intérêt a bien été signalé au client.") url = reverse("tenders:detail-cocontracting-click", kwargs={"slug": self.tender.slug}) - self.assertEqual( - TenderSiae.objects.get(tender=self.tender, siae=self.siae).detail_cocontracting_click_date, None - ) + tendersiae = TenderSiae.objects.get(tender=self.tender, siae=self.siae) + self.assertIsNone(tendersiae.detail_cocontracting_click_date) with mock.patch("lemarche.www.tenders.tasks.send_mail_async") as mock_send_mail_async: response = self.client.post(url, data={}) + tendersiae = TenderSiae.objects.get(tender=self.tender, siae=self.siae) self.assertContains(response, "Votre intérêt a bien été signalé au client.") mock_send_mail_async.assert_called_once() email_body = mock_send_mail_async.call_args[1]["email_body"] self.assertTrue(f"La structure {self.siae.name } souhaite répondre en co-traitance" in email_body) - self.assertNotEqual( - TenderSiae.objects.get(tender=self.tender, siae=self.siae).detail_cocontracting_click_date, None - ) + self.assertIsNotNone(tendersiae.detail_cocontracting_click_date) response = self.client.get(detail_url) self.assertContains(response, "Votre intérêt a bien été signalé au client.") @@ -1330,8 +1326,9 @@ def test_user_can_notify_not_interested_wish_with_siae_id(self): self.assertEqual(response.status_code, 403) # missing siae response = self.client.post(f"{url}?siae_id=999999", data={}) + tendersiae = TenderSiae.objects.get(tender=self.tender, siae=self.siae) self.assertContains(response, self.cta_message_error) - self.assertIsNone(TenderSiae.objects.get(tender=self.tender, siae=self.siae).detail_not_interested_click_date) + self.assertIsNone(tendersiae.detail_not_interested_click_date) detail_url = reverse("tenders:detail", kwargs={"slug": self.tender.slug}) + f"?siae_id={self.siae.id}" response = self.client.get(detail_url) @@ -1339,10 +1336,9 @@ def test_user_can_notify_not_interested_wish_with_siae_id(self): self.assertNotContains(response, self.cta_message_success) response = self.client.post(f"{url}?siae_id={self.siae.id}", data={}) + tendersiae = TenderSiae.objects.get(tender=self.tender, siae=self.siae) self.assertContains(response, self.cta_message_success) - self.assertIsNotNone( - TenderSiae.objects.get(tender=self.tender, siae=self.siae).detail_not_interested_click_date - ) + self.assertIsNotNone(tendersiae.detail_not_interested_click_date) response = self.client.get(detail_url) self.assertContains(response, self.cta_message_success) self.assertNotContains(response, self.cta_message) @@ -1356,12 +1352,13 @@ def test_user_can_notify_not_interested_wish_with_authenticated_user(self): self.assertNotContains(response, self.cta_message_success) url = reverse("tenders:detail-not-interested-click", kwargs={"slug": self.tender.slug}) - self.assertIsNone(TenderSiae.objects.get(tender=self.tender, siae=self.siae).detail_not_interested_click_date) - response = self.client.post(url, data={}) + tendersiae = TenderSiae.objects.get(tender=self.tender, siae=self.siae) + self.assertIsNone(tendersiae.detail_not_interested_click_date) + response = self.client.post(url, data={"detail_not_interested_feedback": "reason"}) + tendersiae = TenderSiae.objects.get(tender=self.tender, siae=self.siae) self.assertContains(response, self.cta_message_success) - self.assertIsNotNone( - TenderSiae.objects.get(tender=self.tender, siae=self.siae).detail_not_interested_click_date - ) + self.assertIsNotNone(tendersiae.detail_not_interested_click_date) + self.assertEqual(tendersiae.detail_not_interested_feedback, "reason") response = self.client.get(detail_url) self.assertContains(response, self.cta_message_success) diff --git a/lemarche/www/tenders/views.py b/lemarche/www/tenders/views.py index d8425fec1..738f4a3c9 100644 --- a/lemarche/www/tenders/views.py +++ b/lemarche/www/tenders/views.py @@ -507,7 +507,11 @@ def post(self, request, *args, **kwargs): # save the datetime of this action TenderSiae.objects.filter( tender=self.object, siae=siae, detail_not_interested_click_date__isnull=True - ).update(detail_not_interested_click_date=timezone.now(), updated_at=timezone.now()) + ).update( + detail_not_interested_feedback=self.request.POST.get("detail_not_interested_feedback", ""), + detail_not_interested_click_date=timezone.now(), + updated_at=timezone.now(), + ) else: self.template_name = "tenders/_detail_not_interested_click_error.html"