From 0adc957c4c25883cb175b380b35e78443f71327a Mon Sep 17 00:00:00 2001 From: Raphael Odini Date: Fri, 29 Mar 2024 09:59:17 +0100 Subject: [PATCH] =?UTF-8?q?feat(Besoins):=20mettre=20=C3=A0=20jour=20l'uti?= =?UTF-8?q?lisateur=20de=20la=20mise=20en=20relation=20(#1144)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lemarche/www/tenders/tasks.py | 17 ++++++++++----- lemarche/www/tenders/tests.py | 41 +++++++++++++++++++++++++++++++---- lemarche/www/tenders/views.py | 17 ++++++++++----- 3 files changed, 61 insertions(+), 14 deletions(-) diff --git a/lemarche/www/tenders/tasks.py b/lemarche/www/tenders/tasks.py index 572201043..0eeba15f1 100644 --- a/lemarche/www/tenders/tasks.py +++ b/lemarche/www/tenders/tasks.py @@ -9,6 +9,7 @@ from lemarche.siaes.models import Siae from lemarche.tenders.models import PartnerShareTender, Tender, TenderSiae +from lemarche.users.models import User from lemarche.utils.apis import api_hubspot, api_mailjet, api_slack from lemarche.utils.data import date_to_string from lemarche.utils.emails import send_mail_async, whitelist_recipient_list @@ -79,7 +80,7 @@ def send_tender_emails_to_siaes(tender: Tender): for user in siae.users.all(): siae_users_count += 1 if user.email != siae.contact_email: - send_tender_email_to_siae(tender, siae, email_subject, email_to_override=user.email) + send_tender_email_to_siae(tender, siae, email_subject, recipient_to_override=user) siae_users_send_count += 1 # log email batch @@ -167,14 +168,20 @@ def send_tender_email_to_partner(email_subject: str, tender: Tender, partner: Pa # @task() -def send_tender_email_to_siae(tender: Tender, siae: Siae, email_subject: str, email_to_override=None): +def send_tender_email_to_siae(tender: Tender, siae: Siae, email_subject: str, recipient_to_override: User = None): # override siae.contact_email if email_to_override is provided - email_to = email_to_override or siae.contact_email + email_to = recipient_to_override.email if recipient_to_override else siae.contact_email recipient_list = whitelist_recipient_list([email_to]) if recipient_list: recipient_email = recipient_list[0] if recipient_list else "" recipient_name = siae.contact_full_name + tender_url = f"{get_object_share_url(tender)}?siae_id={siae.id}" + tender_not_interested_url = f"{get_object_share_url(tender)}?siae_id={siae.id}¬_interested=True" + if recipient_to_override: + tender_url += f"&user_id={recipient_to_override.id}" + tender_not_interested_url += f"&user_id={recipient_to_override.id}" + variables = { "SIAE_CONTACT_FIRST_NAME": siae.contact_first_name, "SIAE_SECTORS": siae.sectors_list_string(), @@ -186,8 +193,8 @@ def send_tender_email_to_siae(tender: Tender, siae: Siae, email_subject: str, em "TENDER_PERIMETERS": tender.location_display, "TENDER_AMOUNT": tender.amount_display, "TENDER_DEADLINE_DATE": date_to_string(tender.deadline_date), - "TENDER_URL": f"{get_object_share_url(tender)}?siae_id={siae.id}", - "TENDER_NOT_INTERESTED_URL": f"{get_object_share_url(tender)}?siae_id={siae.id}¬_interested=True", + "TENDER_URL": tender_url, + "TENDER_NOT_INTERESTED_URL": tender_not_interested_url, } api_mailjet.send_transactional_email_with_template( diff --git a/lemarche/www/tenders/tests.py b/lemarche/www/tenders/tests.py index 7b43bdab1..d55950733 100644 --- a/lemarche/www/tenders/tests.py +++ b/lemarche/www/tenders/tests.py @@ -1134,10 +1134,11 @@ def test_tender_contact_details_display(self): self.assertNotContains(response, "Voir l'appel d'offres") self.assertContains(response, "Lien partagé") - def test_update_tendersiae_stats_on_tender_view(self): - self.tender_1.siaes.add(self.siae_2) + def test_update_tendersiae_stats_on_tender_view_with_siae_id(self): + self.tender_1.siaes.add(self.siae_2) # create new tendersiae self.assertEqual(self.tender_1.tendersiae_set.count(), 3 + 1) self.assertEqual(self.tender_1.tendersiae_set.first().siae, self.siae_2) + self.assertIsNone(self.tender_1.tendersiae_set.first().user) self.assertIsNone(self.tender_1.tendersiae_set.first().email_link_click_date) self.assertIsNone(self.tender_1.tendersiae_set.first().detail_display_date) self.assertEqual(self.tender_1.tendersiae_set.last().siae, self.siae_1) @@ -1148,18 +1149,19 @@ def test_update_tendersiae_stats_on_tender_view(self): response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertContains(response, "Déjà 3 prestataires inclusifs") - # reload anonymous user with ?siae_id= (already in tendersiae) + # reload anonymous user with siae_id (already in tendersiae) url = reverse("tenders:detail", kwargs={"slug": self.tender_1.slug}) + f"?siae_id={self.siae_2.id}" response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertEqual(self.tender_1.tendersiae_set.count(), 4) # unchanged siae_2_email_link_click_date = self.tender_1.tendersiae_set.first().email_link_click_date self.assertIsNotNone(siae_2_email_link_click_date) # email_link_click_date updated + self.assertIsNone(self.tender_1.tendersiae_set.first().user) self.assertIsNone(self.tender_1.tendersiae_set.first().detail_display_date) self.assertIsNotNone(self.tender_1.tendersiae_set.last().detail_display_date) self.assertContains(response, "Déjà 4 prestataires inclusifs") self.assertNotContains(response, "contactez dès maintenant le client") - # reload logged in with ?siae_id= (updats detail_display_date, but not email_link_click_date) + # reload logged in user with siae_id (updates detail_display_date, but not email_link_click_date) self.client.force_login(self.siae_user_2) url = reverse("tenders:detail", kwargs={"slug": self.tender_1.slug}) + f"?siae_id={self.siae_2.id}" response = self.client.get(url) @@ -1180,6 +1182,37 @@ def test_update_tendersiae_stats_on_tender_view(self): self.assertContains(response, "Déjà 4 prestataires inclusifs") self.assertNotContains(response, "contactez dès maintenant le client") + def test_update_tendersiae_stats_on_tender_view_with_siae_id_and_user_id(self): + self.tender_1.siaes.add(self.siae_2) # create new tendersiae + self.assertEqual(self.tender_1.tendersiae_set.count(), 3 + 1) + self.assertEqual(self.tender_1.tendersiae_set.first().siae, self.siae_2) + self.assertIsNone(self.tender_1.tendersiae_set.first().user) + self.assertIsNone(self.tender_1.tendersiae_set.first().email_link_click_date) + self.assertIsNone(self.tender_1.tendersiae_set.first().detail_display_date) + self.assertEqual(self.tender_1.tendersiae_set.last().siae, self.siae_1) + self.assertIsNotNone(self.tender_1.tendersiae_set.last().email_link_click_date) + self.assertIsNotNone(self.tender_1.tendersiae_set.last().detail_display_date) + # first load anonymous user + url = reverse("tenders:detail", kwargs={"slug": self.tender_1.slug}) + response = self.client.get(url) + self.assertEqual(response.status_code, 200) + self.assertContains(response, "Déjà 3 prestataires inclusifs") + # reload anonymous user with siae_id & user_id (already in tendersiae) + url = ( + reverse("tenders:detail", kwargs={"slug": self.tender_1.slug}) + + f"?siae_id={self.siae_2.id}&user_id={self.siae_user_2.id}" + ) + response = self.client.get(url) + self.assertEqual(response.status_code, 200) + self.assertEqual(self.tender_1.tendersiae_set.count(), 4) # unchanged + siae_2_email_link_click_date = self.tender_1.tendersiae_set.first().email_link_click_date + self.assertIsNotNone(siae_2_email_link_click_date) # email_link_click_date updated + self.assertIsNotNone(self.tender_1.tendersiae_set.first().user) # user updated + self.assertIsNone(self.tender_1.tendersiae_set.first().detail_display_date) + self.assertIsNotNone(self.tender_1.tendersiae_set.last().detail_display_date) + self.assertContains(response, "Déjà 4 prestataires inclusifs") + self.assertNotContains(response, "contactez dès maintenant le client") + def test_create_tendersiae_stats_on_tender_view_by_existing_user(self): self.tender_1.siaes.add(self.siae_2) self.assertEqual(self.tender_1.tendersiae_set.count(), 3 + 1) diff --git a/lemarche/www/tenders/views.py b/lemarche/www/tenders/views.py index e006cac8c..fe974ca8c 100644 --- a/lemarche/www/tenders/views.py +++ b/lemarche/www/tenders/views.py @@ -344,11 +344,17 @@ def get(self, request, *args, **kwargs): self.object = self.get_object() user = self.request.user self.siae_id = request.GET.get("siae_id", None) + self.user_id = request.GET.get("user_id", None) # update 'email_link_click_date' if self.siae_id: - TenderSiae.objects.filter(tender=self.object, siae_id=self.siae_id, email_link_click_date=None).update( - email_link_click_date=timezone.now(), updated_at=timezone.now() - ) + if self.user_id: # TODO: check if user in siae ? + TenderSiae.objects.filter( + tender=self.object, siae_id=int(self.siae_id), email_link_click_date=None + ).update(user_id=int(self.user_id), email_link_click_date=timezone.now(), updated_at=timezone.now()) + else: + TenderSiae.objects.filter( + tender=self.object, siae_id=int(self.siae_id), email_link_click_date=None + ).update(email_link_click_date=timezone.now(), updated_at=timezone.now()) # update 'detail_display_date' if user.is_authenticated: if user.kind == User.KIND_SIAE: @@ -358,7 +364,7 @@ def get(self, request, *args, **kwargs): self.is_new_for_siaes = True and not self.object.deadline_date_outdated for siae in user.siaes.all(): TenderSiae.objects.create( - tender=self.object, siae=siae, source=tender_constants.TENDER_SIAE_SOURCE_LINK + tender=self.object, siae=siae, user=user, source=tender_constants.TENDER_SIAE_SOURCE_LINK ) # update stats TenderSiae.objects.filter( @@ -445,7 +451,7 @@ def post(self, request, *args, **kwargs): if user.is_authenticated: TenderSiae.objects.filter( tender=self.object, siae__in=user.siaes.all(), detail_contact_click_date__isnull=True - ).update(detail_contact_click_date=timezone.now(), updated_at=timezone.now()) + ).update(user=user, detail_contact_click_date=timezone.now(), updated_at=timezone.now()) else: TenderSiae.objects.filter( tender=self.object, siae_id=int(siae_id), detail_contact_click_date__isnull=True @@ -531,6 +537,7 @@ def post(self, request, *args, **kwargs): TenderSiae.objects.filter( tender=self.object, siae__in=user.siaes.all(), detail_not_interested_click_date__isnull=True ).update( + user=user, detail_not_interested_feedback=self.request.POST.get("detail_not_interested_feedback", ""), detail_not_interested_click_date=timezone.now(), updated_at=timezone.now(),