From 7d8b8c3347a04688219c844375d07568a51ba468 Mon Sep 17 00:00:00 2001 From: Raphael Odini Date: Mon, 25 Mar 2024 17:16:41 +0100 Subject: [PATCH 1/4] On TenderSiae change, update user data --- lemarche/www/tenders/views.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lemarche/www/tenders/views.py b/lemarche/www/tenders/views.py index e006cac8c..2dd2a0a16 100644 --- a/lemarche/www/tenders/views.py +++ b/lemarche/www/tenders/views.py @@ -358,7 +358,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 +445,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 +531,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(), From bb45c9d6bbe2b137b179cb5cd2ae0e13882b7d85 Mon Sep 17 00:00:00 2001 From: Raphael Odini Date: Wed, 27 Mar 2024 11:31:29 +0100 Subject: [PATCH 2/4] Send user_id --- lemarche/www/tenders/tasks.py | 17 ++++++++++++----- lemarche/www/tenders/views.py | 12 +++++++++--- 2 files changed, 21 insertions(+), 8 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/views.py b/lemarche/www/tenders/views.py index 2dd2a0a16..1a7c06023 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: + TenderSiae.objects.filter(tender=self.object, siae_id=self.siae_id, email_link_click_date=None).update( + user_id=self.user_id, email_link_click_date=timezone.now(), updated_at=timezone.now() + ) + else: + 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() + ) # update 'detail_display_date' if user.is_authenticated: if user.kind == User.KIND_SIAE: From 2eaf257ac185d8f0b7e0b5c708a024ad4bb89186 Mon Sep 17 00:00:00 2001 From: Raphael Odini Date: Wed, 27 Mar 2024 11:40:12 +0100 Subject: [PATCH 3/4] Add test --- lemarche/www/tenders/tests.py | 41 +++++++++++++++++++++++++++++++---- lemarche/www/tenders/views.py | 2 +- 2 files changed, 38 insertions(+), 5 deletions(-) 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 1a7c06023..76ab580d1 100644 --- a/lemarche/www/tenders/views.py +++ b/lemarche/www/tenders/views.py @@ -347,7 +347,7 @@ def get(self, request, *args, **kwargs): self.user_id = request.GET.get("user_id", None) # update 'email_link_click_date' if self.siae_id: - if self.user_id: + if self.user_id: # TODO: check if user in siae ? TenderSiae.objects.filter(tender=self.object, siae_id=self.siae_id, email_link_click_date=None).update( user_id=self.user_id, email_link_click_date=timezone.now(), updated_at=timezone.now() ) From 08454defa6b5704b499b1c6bf9c447026c9c4856 Mon Sep 17 00:00:00 2001 From: Raphael Odini Date: Fri, 29 Mar 2024 09:53:51 +0100 Subject: [PATCH 4/4] String to int --- lemarche/www/tenders/views.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lemarche/www/tenders/views.py b/lemarche/www/tenders/views.py index 76ab580d1..fe974ca8c 100644 --- a/lemarche/www/tenders/views.py +++ b/lemarche/www/tenders/views.py @@ -348,13 +348,13 @@ def get(self, request, *args, **kwargs): # update 'email_link_click_date' if self.siae_id: if self.user_id: # TODO: check if user in siae ? - TenderSiae.objects.filter(tender=self.object, siae_id=self.siae_id, email_link_click_date=None).update( - user_id=self.user_id, email_link_click_date=timezone.now(), updated_at=timezone.now() - ) + 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=self.siae_id, email_link_click_date=None).update( - email_link_click_date=timezone.now(), updated_at=timezone.now() - ) + 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: