Skip to content

Commit

Permalink
Dépôt de besoin : pouvoir indiquer la raison du non intérêt (#1045)
Browse files Browse the repository at this point in the history
* New field TenderSiae.detail_not_interested_feedback

* Add new field to template. Update view

* Update tests
  • Loading branch information
raphodn authored Jan 18, 2024
1 parent 43864dd commit 673c445
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 31 deletions.
31 changes: 23 additions & 8 deletions lemarche/templates/tenders/_detail_cta_not_interested.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,29 @@ <h3>Pas intéressé ?</h3>
<p>
Cette demande ne vous intéresse pas ? Dites-le nous !
</p>
{% if user.is_authenticated %}
<button type="button" class="btn btn-warning btn-block" title="Je ne suis pas intéressé" hx-post="{% url 'tenders:detail-not-interested-click' tender.slug %}" hx-target="#detail_not_interested_container">
Je ne suis pas intéressé
</button>
{% elif siae_id %}
<button type="button" class="btn btn-warning btn-block" title="Je ne suis pas intéressé" hx-post="{% url 'tenders:detail-not-interested-click' tender.slug %}?siae_id={{siae_id}}" hx-target="#detail_not_interested_container">
Je ne suis pas intéressé
</button>
{% if user_can_click %}
<form method="POST" action="{% url 'tenders:detail-not-interested-click' tender.slug %}?siae_id=">
{% csrf_token %}
<div class="form-group">
<label for="id_detail_not_interested_feedback">Afin d'améliorer la pertinence des demandes que nous vous envoyons, expliquez-nous pourquoi celle-ci ne vous intéresse pas.</label>
<textarea id="id_detail_not_interested_feedback" class="form-control" name="detail_not_interested_feedback" placeholder="Parce que..." rows="3"></textarea>
</div>
<div>
{% if user.is_authenticated %}
<button type="submit" class="btn btn-warning btn-block" title="{{ tender.cta_not_interested_card_button_text|safe }}" hx-post="{% url 'tenders:detail-not-interested-click' tender.slug %}" hx-target="#detail_not_interested_container">
<span>{{ tender.cta_not_interested_card_button_text|safe }}</span>
</button>
{% elif siae_id %}
<button type="submit" class="btn btn-warning btn-block" title="{{ tender.cta_not_interested_card_button_text|safe }}" hx-post="{% url 'tenders:detail-not-interested-click' tender.slug %}?siae_id={{siae_id}}" hx-target="#detail_not_interested_container">
<span>{{ tender.cta_not_interested_card_button_text|safe }}</span>
</button>
{% endif %}
</div>
</form>
{% else %}
<a href="#" id="show-tender-not-interested-modal-btn" class="btn btn-primary btn-block" data-toggle="modal" data-target="#login_or_signup_siae_tender_modal" data-next-params="{% url 'tenders:detail' tender.slug %}">
<span>{{ tender.cta_not_interested_card_button_text|safe }}</span>
</a>
{% endif %}
</div>
</div>
Expand Down
3 changes: 2 additions & 1 deletion lemarche/templates/tenders/detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -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 %}
Expand All @@ -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 %}
Expand Down
Original file line number Diff line number Diff line change
@@ -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"),
),
]
5 changes: 5 additions & 0 deletions lemarche/tenders/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
39 changes: 18 additions & 21 deletions lemarche/www/tenders/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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 ?")
Expand All @@ -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.")
Expand Down Expand Up @@ -1330,19 +1326,19 @@ 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)
self.assertContains(response, self.cta_message)
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)
Expand All @@ -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)
Expand Down
6 changes: 5 additions & 1 deletion lemarche/www/tenders/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down

0 comments on commit 673c445

Please sign in to comment.