From 16f42f6240eeb86a34112851b6ae56bcf409ea3c Mon Sep 17 00:00:00 2001 From: Raphael Odini Date: Fri, 20 Oct 2023 15:25:52 +0200 Subject: [PATCH] Siae & Tender: update annotated count --- lemarche/favorites/tests.py | 16 +-- lemarche/siaes/admin.py | 68 ++++++------- lemarche/siaes/factories.py | 9 +- lemarche/siaes/models.py | 50 ++++------ lemarche/siaes/tests.py | 78 +++++++++------ .../templates/dashboard/siae_edit_info.html | 6 +- .../networks/dashboard_network_siae_list.html | 14 +-- .../dashboard_network_siae_tender_list.html | 6 +- .../dashboard_network_tender_detail.html | 4 +- .../dashboard_network_tender_siae_list.html | 4 +- lemarche/templates/siaes/_card_detail.html | 2 +- .../templates/siaes/_card_search_result.html | 2 +- .../templates/tenders/_list_item_buyer.html | 12 +-- .../templates/tenders/_list_item_network.html | 4 +- lemarche/tenders/admin.py | 99 ++++++++++--------- lemarche/tenders/models.py | 24 ++--- lemarche/tenders/tests.py | 91 +++++++++-------- lemarche/www/dashboard_networks/views.py | 2 +- lemarche/www/dashboard_siaes/views.py | 4 +- lemarche/www/siaes/forms.py | 10 +- lemarche/www/siaes/views.py | 4 +- 21 files changed, 263 insertions(+), 246 deletions(-) diff --git a/lemarche/favorites/tests.py b/lemarche/favorites/tests.py index fb8fa3bd6..ca011dcff 100644 --- a/lemarche/favorites/tests.py +++ b/lemarche/favorites/tests.py @@ -50,17 +50,9 @@ def test_with_siae_stats(self): self.assertEqual(favorite_list_queryset.get(id=favorite_list.id).siae_count_annotated, 0) self.assertEqual(favorite_list_queryset.get(id=favorite_list_with_siaes.id).siae_count_annotated, 2) - def test_siae_annotate_with_user_favorite_list_count(self): + def test_siae_with_in_user_favorite_list_stats(self): FavoriteListFactory(user=self.user, siaes=[self.siae_1]) FavoriteListFactory(user=self.user, siaes=[self.siae_1]) - siae_queryset = Siae.objects.annotate_with_user_favorite_list_count(self.user) - self.assertEqual(siae_queryset.get(id=self.siae_1.id).in_user_favorite_list_count, 2) - self.assertEqual(siae_queryset.get(id=self.siae_2.id).in_user_favorite_list_count, 0) - - def test_siae_annotate_with_user_favorite_list_ids(self): - favorite_list_1 = FavoriteListFactory(user=self.user, siaes=[self.siae_1]) - FavoriteListFactory(user=self.user, siaes=[self.siae_1]) - siae_queryset = Siae.objects.annotate_with_user_favorite_list_ids(self.user) - self.assertEqual(len(siae_queryset.get(id=self.siae_1.id).in_user_favorite_list_ids), 2) - self.assertEqual(len(siae_queryset.get(id=self.siae_2.id).in_user_favorite_list_ids), 0) - self.assertEqual(siae_queryset.get(id=self.siae_1.id).in_user_favorite_list_ids[0], favorite_list_1.id) + siae_queryset = Siae.objects.with_in_user_favorite_list_stats(self.user) + self.assertEqual(siae_queryset.get(id=self.siae_1.id).in_user_favorite_list_count_annotated, 2) + self.assertEqual(siae_queryset.get(id=self.siae_2.id).in_user_favorite_list_count_annotated, 0) diff --git a/lemarche/siaes/admin.py b/lemarche/siaes/admin.py index 6c2cb0b04..e619eb752 100644 --- a/lemarche/siaes/admin.py +++ b/lemarche/siaes/admin.py @@ -141,9 +141,9 @@ class SiaeAdmin(FieldsetsInlineMixin, gis_admin.OSMGeoAdmin): "label_count_with_link", "client_reference_count_with_link", "image_count_with_link", - "tender_email_send_count_with_link", - "tender_detail_display_count_with_link", - "tender_detail_contact_click_count_with_link", + "tender_email_send_count_annotated_with_link", + "tender_detail_display_count_annotated_with_link", + "tender_detail_contact_click_count_annotated_with_link", "created_at", ] list_filter = [ @@ -175,11 +175,11 @@ class SiaeAdmin(FieldsetsInlineMixin, gis_admin.OSMGeoAdmin): "coords_display", "logo_url", "logo_url_display", - "tender_count_with_link", - "tender_email_send_count_with_link", - "tender_email_link_click_count_with_link", - "tender_detail_display_count_with_link", - "tender_detail_contact_click_count_with_link", + "tender_count_annotated_with_link", + "tender_email_send_count_annotated_with_link", + "tender_email_link_click_count_annotated_with_link", + "tender_detail_display_count_annotated_with_link", + "tender_detail_contact_click_count_annotated_with_link", "logs_display", # "import_raw_object", "import_raw_object_display", @@ -295,11 +295,11 @@ class SiaeAdmin(FieldsetsInlineMixin, gis_admin.OSMGeoAdmin): "Besoins des acheteurs", { "fields": ( - "tender_count_with_link", - "tender_email_send_count_with_link", - "tender_email_link_click_count_with_link", - "tender_detail_display_count_with_link", - "tender_detail_contact_click_count_with_link", + "tender_count_annotated_with_link", + "tender_email_send_count_annotated_with_link", + "tender_email_link_click_count_annotated_with_link", + "tender_detail_display_count_annotated_with_link", + "tender_detail_contact_click_count_annotated_with_link", ) }, ), @@ -531,52 +531,54 @@ def import_raw_object_display(self, instance: Siae = None): import_raw_object_display.short_description = Siae._meta.get_field("import_raw_object").verbose_name - def tender_count_with_link(self, siae): + def tender_count_annotated_with_link(self, siae): url = reverse("admin:tenders_tender_changelist") + f"?siaes__in={siae.id}" - return format_html(f'{getattr(siae, "tender_count", 0)}') + return format_html(f'{getattr(siae, "tender_count_annotated", 0)}') - tender_count_with_link.short_description = "Besoins concernés" - tender_count_with_link.admin_order_field = "tender_count" + tender_count_annotated_with_link.short_description = "Besoins concernés" + tender_count_annotated_with_link.admin_order_field = "tender_count_annotated" - def tender_email_send_count_with_link(self, siae): + def tender_email_send_count_annotated_with_link(self, siae): url = ( reverse("admin:tenders_tender_changelist") + f"?siaes__in={siae.id}&tendersiae__email_send_date__isnull=False" ) - return format_html(f'{getattr(siae, "tender_email_send_count", 0)}') + return format_html(f'{getattr(siae, "tender_email_send_count_annotated", 0)}') - tender_email_send_count_with_link.short_description = "Besoins reçus" - tender_email_send_count_with_link.admin_order_field = "tender_email_send_count" + tender_email_send_count_annotated_with_link.short_description = "Besoins reçus" + tender_email_send_count_annotated_with_link.admin_order_field = "tender_email_send_count_annotated" - def tender_email_link_click_count_with_link(self, siae): + def tender_email_link_click_count_annotated_with_link(self, siae): url = ( reverse("admin:tenders_tender_changelist") + f"?siaes__in={siae.id}&tendersiae__email_link_click_date__isnull=False" ) - return format_html(f'{getattr(siae, "tender_email_link_click_count", 0)}') + return format_html(f'{getattr(siae, "tender_email_link_click_count_annotated", 0)}') - tender_email_link_click_count_with_link.short_description = "Besoins cliqués" - tender_email_link_click_count_with_link.admin_order_field = "tender_email_link_click_count" + tender_email_link_click_count_annotated_with_link.short_description = "Besoins cliqués" + tender_email_link_click_count_annotated_with_link.admin_order_field = "tender_email_link_click_count_annotated" - def tender_detail_display_count_with_link(self, siae): + def tender_detail_display_count_annotated_with_link(self, siae): url = ( reverse("admin:tenders_tender_changelist") + f"?siaes__in={siae.id}&tendersiae__detail_display_date__isnull=False" ) - return format_html(f'{getattr(siae, "tender_detail_display_count", 0)}') + return format_html(f'{getattr(siae, "tender_detail_display_count_annotated", 0)}') - tender_detail_display_count_with_link.short_description = "Besoins vues" - tender_detail_display_count_with_link.admin_order_field = "tender_detail_display_count" + tender_detail_display_count_annotated_with_link.short_description = "Besoins vues" + tender_detail_display_count_annotated_with_link.admin_order_field = "tender_detail_display_count_annotated" - def tender_detail_contact_click_count_with_link(self, siae): + def tender_detail_contact_click_count_annotated_with_link(self, siae): url = ( reverse("admin:tenders_tender_changelist") + f"?siaes__in={siae.id}&tendersiae__detail_contact_click_date__isnull=False" ) - return format_html(f'{getattr(siae, "tender_detail_contact_click_count", 0)}') + return format_html(f'{getattr(siae, "tender_detail_contact_click_count_annotated", 0)}') - tender_detail_contact_click_count_with_link.short_description = "Besoins intéressés" - tender_detail_contact_click_count_with_link.admin_order_field = "tender_detail_contact_click_count" + tender_detail_contact_click_count_annotated_with_link.short_description = "Besoins intéressés" + tender_detail_contact_click_count_annotated_with_link.admin_order_field = ( + "tender_detail_contact_click_count_annotated" + ) def logs_display(self, siae=None): if siae: diff --git a/lemarche/siaes/factories.py b/lemarche/siaes/factories.py index f77bd586e..9f4dad352 100644 --- a/lemarche/siaes/factories.py +++ b/lemarche/siaes/factories.py @@ -4,7 +4,7 @@ from factory.django import DjangoModelFactory from lemarche.siaes import constants as siae_constants -from lemarche.siaes.models import Siae, SiaeClientReference, SiaeGroup, SiaeLabelOld, SiaeOffer +from lemarche.siaes.models import Siae, SiaeClientReference, SiaeGroup, SiaeImage, SiaeLabelOld, SiaeOffer class SiaeGroupFactory(DjangoModelFactory): @@ -75,3 +75,10 @@ class Meta: model = SiaeLabelOld name = factory.Faker("name", locale="fr_FR") + + +class SiaeImageFactory(DjangoModelFactory): + class Meta: + model = SiaeImage + + name = factory.Faker("name", locale="fr_FR") diff --git a/lemarche/siaes/models.py b/lemarche/siaes/models.py index 621630899..430a2678f 100644 --- a/lemarche/siaes/models.py +++ b/lemarche/siaes/models.py @@ -5,7 +5,6 @@ from django.contrib.gis.db import models as gis_models from django.contrib.gis.db.models.functions import Distance from django.contrib.gis.measure import D -from django.contrib.postgres.aggregates import ArrayAgg from django.contrib.postgres.search import TrigramSimilarity # SearchVector from django.db import IntegrityError, models, transaction from django.db.models import BooleanField, Case, CharField, Count, F, IntegerField, PositiveIntegerField, Q, Sum, When @@ -312,20 +311,12 @@ def with_country_geo_range(self): def exclude_country_geo_range(self): return self.exclude(Q(geo_range=siae_constants.GEO_RANGE_COUNTRY)) - def annotate_with_user_favorite_list_count(self, user): + def with_in_user_favorite_list_stats(self, user): """ Enrich each Siae with the number of occurences in the user's favorite lists """ return self.prefetch_related("favorite_lists").annotate( - in_user_favorite_list_count=Count("favorite_lists", filter=Q(favorite_lists__user=user)) - ) - - def annotate_with_user_favorite_list_ids(self, user): - """ - Enrich each Siae with the list of occurences in the user's favorite lists - """ - return self.prefetch_related("favorite_lists").annotate( - in_user_favorite_list_ids=ArrayAgg("favorite_lists__pk", filter=Q(favorite_lists__user=user)) + in_user_favorite_list_count_annotated=Count("favorite_lists", filter=Q(favorite_lists__user=user)) ) def has_contact_email(self): @@ -371,23 +362,23 @@ def with_tender_stats(self): Enrich each Siae with stats on their linked Tender """ return self.annotate( - tender_count=Count("tenders", distinct=True), - tender_email_send_count=Sum( + tender_count_annotated=Count("tenders", distinct=True), + tender_email_send_count_annotated=Sum( Case(When(tendersiae__email_send_date__isnull=False, then=1), default=0, output_field=IntegerField()) ), - tender_email_link_click_count=Sum( + tender_email_link_click_count_annotated=Sum( Case( When(tendersiae__email_link_click_date__isnull=False, then=1), default=0, output_field=IntegerField(), ) ), - tender_detail_display_count=Sum( + tender_detail_display_count_annotated=Sum( Case( When(tendersiae__detail_display_date__isnull=False, then=1), default=0, output_field=IntegerField() ) ), - tender_detail_contact_click_count=Sum( + tender_detail_contact_click_count_annotated=Sum( Case( When(tendersiae__detail_contact_click_date__isnull=False, then=1), default=0, @@ -396,16 +387,16 @@ def with_tender_stats(self): ), ) - def annotate_with_brand_or_name(self, with_order_by=False): + def with_brand_or_name(self, with_order_by=False): """ We usually want to display the brand by default See Siae.name_display() """ qs = self.annotate( - brand_or_name=Case(When(brand="", then=F("name")), default=F("brand"), output_field=CharField()) + brand_or_name_annotated=Case(When(brand="", then=F("name")), default=F("brand"), output_field=CharField()) ) if with_order_by: - qs = qs.order_by("brand_or_name") + qs = qs.order_by("brand_or_name_annotated") return qs def with_content_filled_stats(self): @@ -417,12 +408,12 @@ def with_content_filled_stats(self): - Level 4 (full): user_count + sector_count + description + logo + client_reference_count + image_count + label_count # noqa """ return self.annotate( - content_filled_basic=Case( + content_filled_basic_annotated=Case( When(Q(user_count__gte=1) & Q(sector_count__gte=1) & ~Q(description=""), then=True), default=False, output_field=BooleanField(), ), - content_filled_full=Case( + content_filled_full_annotated=Case( When( Q(user_count__gte=1) & Q(sector_count__gte=1) @@ -441,24 +432,23 @@ def with_content_filled_stats(self): def content_not_filled(self): return self.filter(Q(sector_count=0) | Q(contact_email="")) - def with_employees_count(self): + def with_employees_stats(self): """ Enrich each Siae with count of employees Annotate first to use the field "c2_etp_count" if employees_insertion_count is null Next, the sum of an integer and a null value is null, so we check if fields are not null before make sum """ return self.annotate( - employees_insertion_count_with_c2_etp=Case( + employees_insertion_count_with_c2_etp_annotated=Case( When(employees_insertion_count=None, then=Round(F("c2_etp_count"))), default=F("employees_insertion_count"), output_field=PositiveIntegerField(), - ) - ).annotate( - employees_count=Case( - When(employees_insertion_count_with_c2_etp=None, then=F("employees_permanent_count")), - When(employees_permanent_count=None, then=F("employees_insertion_count_with_c2_etp")), - default=F("employees_insertion_count_with_c2_etp") + F("employees_permanent_count"), - ) + ), + employees_count_annotated=Case( + When(employees_insertion_count_with_c2_etp_annotated=None, then=F("employees_permanent_count")), + When(employees_permanent_count=None, then=F("employees_insertion_count_with_c2_etp_annotated")), + default=F("employees_insertion_count_with_c2_etp_annotated") + F("employees_permanent_count"), + ), ) diff --git a/lemarche/siaes/tests.py b/lemarche/siaes/tests.py index 137cc45ea..d826ec2d3 100644 --- a/lemarche/siaes/tests.py +++ b/lemarche/siaes/tests.py @@ -6,7 +6,14 @@ from lemarche.perimeters.models import Perimeter from lemarche.sectors.factories import SectorFactory from lemarche.siaes import constants as siae_constants, utils as siae_utils -from lemarche.siaes.factories import SiaeFactory, SiaeGroupFactory, SiaeLabelOldFactory, SiaeOfferFactory +from lemarche.siaes.factories import ( + SiaeClientReferenceFactory, + SiaeFactory, + SiaeGroupFactory, + SiaeImageFactory, + SiaeLabelOldFactory, + SiaeOfferFactory, +) from lemarche.siaes.models import Siae, SiaeGroup, SiaeLabel, SiaeUser from lemarche.users.factories import UserFactory @@ -345,32 +352,43 @@ def test_has_user_queryset(self): self.assertEqual(Siae.objects.count(), 2) self.assertEqual(Siae.objects.has_user().count(), 1) - # def test_annotate_with_user_favorite_list_ids(self): + # def test_with_in_user_favorite_list_stats(self): # see favorites > tests.py # def test_with_tender_stats(self): # see tenders > tests.py > TenderModelQuerysetStatsTest - def test_annotate_with_brand_or_name(self): + def test_with_brand_or_name(self): siae_1 = SiaeFactory(name="ZZZ", brand="ABC") siae_2 = SiaeFactory(name="Test", brand="") - siae_queryset = Siae.objects.annotate_with_brand_or_name() - self.assertEqual(siae_queryset.get(id=siae_1.id).brand_or_name, siae_1.brand) - self.assertEqual(siae_queryset.get(id=siae_2.id).brand_or_name, siae_2.name) + siae_queryset = Siae.objects.with_brand_or_name() + self.assertEqual(siae_queryset.get(id=siae_1.id).brand_or_name_annotated, siae_1.brand) + self.assertEqual(siae_queryset.get(id=siae_2.id).brand_or_name_annotated, siae_2.name) self.assertEqual(siae_queryset.first(), siae_2) # default order is by "name" - siae_queryset_with_order_by = Siae.objects.annotate_with_brand_or_name().order_by("brand_or_name") + siae_queryset_with_order_by = Siae.objects.with_brand_or_name().order_by("brand_or_name_annotated") self.assertEqual(siae_queryset_with_order_by.first(), siae_1) - siae_queryset_with_order_by_parameter = Siae.objects.annotate_with_brand_or_name(with_order_by=True) + siae_queryset_with_order_by_parameter = Siae.objects.with_brand_or_name(with_order_by=True) self.assertEqual(siae_queryset_with_order_by_parameter.first(), siae_1) def test_with_content_filled_stats(self): siae_empty = SiaeFactory(name="Empty") - siae_filled_basic = SiaeFactory(name="Filled basic", user_count=1, sector_count=2, description="desc") + siae_filled_basic = SiaeFactory(name="Filled basic", user_count=1, sector_count=1, description="desc") + siae_filled_full = SiaeFactory( + name="Filled full", user_count=1, sector_count=1, description="desc", logo_url="https://logo.png" + ) + SiaeClientReferenceFactory(siae=siae_filled_full) + SiaeImageFactory(siae=siae_filled_full) + SiaeLabelOldFactory(siae=siae_filled_full) + siae_filled_full.save() siae_queryset = Siae.objects.with_content_filled_stats() - self.assertEqual(siae_queryset.get(id=siae_empty.id).content_filled_basic, False) - self.assertEqual(siae_queryset.get(id=siae_filled_basic.id).content_filled_basic, True) - - def test_with_employees_count(self): + self.assertEqual(siae_queryset.get(id=siae_empty.id).content_filled_basic_annotated, False) + self.assertEqual(siae_queryset.get(id=siae_empty.id).content_filled_full_annotated, False) + self.assertEqual(siae_queryset.get(id=siae_filled_basic.id).content_filled_basic_annotated, True) + self.assertEqual(siae_queryset.get(id=siae_filled_basic.id).content_filled_full_annotated, False) + self.assertEqual(siae_queryset.get(id=siae_filled_full.id).content_filled_basic_annotated, True) + self.assertEqual(siae_queryset.get(id=siae_filled_full.id).content_filled_full_annotated, True) + + def test_with_employees_stats(self): siae_1 = SiaeFactory() siae_2 = SiaeFactory(employees_insertion_count=10) siae_3 = SiaeFactory(c2_etp_count=19.5) @@ -380,30 +398,30 @@ def test_with_employees_count(self): siae_7 = SiaeFactory(c2_etp_count=2550, employees_permanent_count=1500) siae_8 = SiaeFactory(employees_insertion_count=125, c2_etp_count=158, employees_permanent_count=88) - siae_queryset = Siae.objects.with_employees_count() - self.assertEqual(siae_queryset.get(id=siae_1.id).employees_insertion_count_with_c2_etp, None) - self.assertEqual(siae_queryset.get(id=siae_1.id).employees_count, None) + siae_queryset = Siae.objects.with_employees_stats() + self.assertEqual(siae_queryset.get(id=siae_1.id).employees_insertion_count_with_c2_etp_annotated, None) + self.assertEqual(siae_queryset.get(id=siae_1.id).employees_count_annotated, None) - self.assertEqual(siae_queryset.get(id=siae_2.id).employees_insertion_count_with_c2_etp, 10) - self.assertEqual(siae_queryset.get(id=siae_2.id).employees_count, 10) + self.assertEqual(siae_queryset.get(id=siae_2.id).employees_insertion_count_with_c2_etp_annotated, 10) + self.assertEqual(siae_queryset.get(id=siae_2.id).employees_count_annotated, 10) - self.assertEqual(siae_queryset.get(id=siae_3.id).employees_insertion_count_with_c2_etp, 20) - self.assertEqual(siae_queryset.get(id=siae_3.id).employees_count, 20) + self.assertEqual(siae_queryset.get(id=siae_3.id).employees_insertion_count_with_c2_etp_annotated, 20) + self.assertEqual(siae_queryset.get(id=siae_3.id).employees_count_annotated, 20) - self.assertEqual(siae_queryset.get(id=siae_4.id).employees_insertion_count_with_c2_etp, None) - self.assertEqual(siae_queryset.get(id=siae_4.id).employees_count, 155) + self.assertEqual(siae_queryset.get(id=siae_4.id).employees_insertion_count_with_c2_etp_annotated, None) + self.assertEqual(siae_queryset.get(id=siae_4.id).employees_count_annotated, 155) - self.assertEqual(siae_queryset.get(id=siae_5.id).employees_insertion_count_with_c2_etp, 22) - self.assertEqual(siae_queryset.get(id=siae_5.id).employees_count, 22) + self.assertEqual(siae_queryset.get(id=siae_5.id).employees_insertion_count_with_c2_etp_annotated, 22) + self.assertEqual(siae_queryset.get(id=siae_5.id).employees_count_annotated, 22) - self.assertEqual(siae_queryset.get(id=siae_6.id).employees_insertion_count_with_c2_etp, 280) - self.assertEqual(siae_queryset.get(id=siae_6.id).employees_count, 280 + 105) + self.assertEqual(siae_queryset.get(id=siae_6.id).employees_insertion_count_with_c2_etp_annotated, 280) + self.assertEqual(siae_queryset.get(id=siae_6.id).employees_count_annotated, 280 + 105) - self.assertEqual(siae_queryset.get(id=siae_7.id).employees_insertion_count_with_c2_etp, 2550) - self.assertEqual(siae_queryset.get(id=siae_7.id).employees_count, 2550 + 1500) + self.assertEqual(siae_queryset.get(id=siae_7.id).employees_insertion_count_with_c2_etp_annotated, 2550) + self.assertEqual(siae_queryset.get(id=siae_7.id).employees_count_annotated, 2550 + 1500) - self.assertEqual(siae_queryset.get(id=siae_8.id).employees_insertion_count_with_c2_etp, 125) - self.assertEqual(siae_queryset.get(id=siae_8.id).employees_count, 125 + 88) + self.assertEqual(siae_queryset.get(id=siae_8.id).employees_insertion_count_with_c2_etp_annotated, 125) + self.assertEqual(siae_queryset.get(id=siae_8.id).employees_count_annotated, 125 + 88) class SiaeModelPerimeterQuerysetTest(TestCase): diff --git a/lemarche/templates/dashboard/siae_edit_info.html b/lemarche/templates/dashboard/siae_edit_info.html index 5b002fd1a..7ac058579 100644 --- a/lemarche/templates/dashboard/siae_edit_info.html +++ b/lemarche/templates/dashboard/siae_edit_info.html @@ -41,7 +41,7 @@ - {% if last_3_siae_content_filled_full %} + {% if last_3_siae_content_filled_full_annotated %}
diff --git a/lemarche/templates/networks/dashboard_network_tender_siae_list.html b/lemarche/templates/networks/dashboard_network_tender_siae_list.html index 256473f10..b27bc23e4 100644 --- a/lemarche/templates/networks/dashboard_network_tender_siae_list.html +++ b/lemarche/templates/networks/dashboard_network_tender_siae_list.html @@ -45,7 +45,7 @@

Mes adhérents notifiés et intéressés par cette oppo class="nav-link{% if request.get_full_path == NETWORK_TENDER_SIAE_LIST_URL %} active{% endif %}" hx-target="#siaeTenderList" hx-swap="outerHTML"> Adhérents notifiés - {{ tender.network_siae_email_send_count }} + {{ tender.network_siae_email_send_count_annotated }} diff --git a/lemarche/templates/siaes/_card_detail.html b/lemarche/templates/siaes/_card_detail.html index ad27a9b79..e2c0a4c1e 100644 --- a/lemarche/templates/siaes/_card_detail.html +++ b/lemarche/templates/siaes/_card_detail.html @@ -19,7 +19,7 @@

(profil mis à jour il y a {{ siae.updated_at|timesince }})

{% if user.is_authenticated %} - {% if siae.in_user_favorite_list_count %} + {% if siae.in_user_favorite_list_count_annotated %} diff --git a/lemarche/templates/siaes/_card_search_result.html b/lemarche/templates/siaes/_card_search_result.html index 2a80ee85a..229c83f77 100644 --- a/lemarche/templates/siaes/_card_search_result.html +++ b/lemarche/templates/siaes/_card_search_result.html @@ -38,7 +38,7 @@

{% endif %} {% if user.is_authenticated %} - {% if from_profile or siae.in_user_favorite_list_count %} + {% if from_profile or siae.in_user_favorite_list_count_annotated %} diff --git a/lemarche/templates/tenders/_list_item_buyer.html b/lemarche/templates/tenders/_list_item_buyer.html index 2b8f39ef3..f00044066 100644 --- a/lemarche/templates/tenders/_list_item_buyer.html +++ b/lemarche/templates/tenders/_list_item_buyer.html @@ -44,17 +44,17 @@

{{ tender.title }}


{% if tender.status == tender.STATUS_VALIDATED %} - {% if tender.siae_detail_contact_click_since_last_seen_date_count %} + {% if tender.siae_detail_contact_click_since_last_seen_date_count_annotated %} -  {{ tender.siae_detail_contact_click_since_last_seen_date_count }} nouveau{{ tender.siae_detail_contact_click_since_last_seen_date_count|pluralize:"x" }} prestataire{{ tender.siae_detail_contact_click_since_last_seen_date_count|pluralize }} intéressé{{ tender.siae_detail_contact_click_since_last_seen_date_count|pluralize }} +  {{ tender.siae_detail_contact_click_since_last_seen_date_count_annotated }} nouveau{{ tender.siae_detail_contact_click_since_last_seen_date_count_annotated|pluralize:"x" }} prestataire{{ tender.siae_detail_contact_click_since_last_seen_date_count_annotated|pluralize }} intéressé{{ tender.siae_detail_contact_click_since_last_seen_date_count_annotated|pluralize }} {% endif %}

-  {{ tender.siae_email_send_count|default:0 }} prestataire{{ tender.siae_email_send_count|pluralize }} ciblé{{ tender.siae_email_send_count|pluralize }} +  {{ tender.siae_email_send_count_annotated|default:0 }} prestataire{{ tender.siae_email_send_count_annotated|pluralize }} ciblé{{ tender.siae_email_send_count_annotated|pluralize }}

- {% if tender.siae_email_send_count %} + {% if tender.siae_email_send_count_annotated %} Voir @@ -62,9 +62,9 @@

{{ tender.title }}

-  {{ tender.siae_detail_contact_click_count|default:0 }} prestataire{{ tender.siae_detail_contact_click_count|pluralize }} intéressé{{ tender.siae_detail_contact_click_count|pluralize }} +  {{ tender.siae_detail_contact_click_count_annotated|default:0 }} prestataire{{ tender.siae_detail_contact_click_count_annotated|pluralize }} intéressé{{ tender.siae_detail_contact_click_count_annotated|pluralize }}

- {% if tender.siae_detail_contact_click_count %} + {% if tender.siae_detail_contact_click_count_annotated %} Voir diff --git a/lemarche/templates/tenders/_list_item_network.html b/lemarche/templates/tenders/_list_item_network.html index f5c540c64..91b3dc27b 100644 --- a/lemarche/templates/tenders/_list_item_network.html +++ b/lemarche/templates/tenders/_list_item_network.html @@ -34,9 +34,9 @@

{{ tender.title }}

-  {{ tender.network_siae_email_send_count|default:0 }} adhérent{{ tender.network_siae_email_send_count|pluralize }} notifié{{ tender.network_siae_email_send_count|pluralize }} +  {{ tender.network_siae_email_send_count_annotated|default:0 }} adhérent{{ tender.network_siae_email_send_count_annotated|pluralize }} notifié{{ tender.network_siae_email_send_count_annotated|pluralize }}

- {% if tender.network_siae_email_send_count %} + {% if tender.network_siae_email_send_count_annotated %} Voir la liste diff --git a/lemarche/tenders/admin.py b/lemarche/tenders/admin.py index 0d36f9d88..52464efc2 100644 --- a/lemarche/tenders/admin.py +++ b/lemarche/tenders/admin.py @@ -129,12 +129,12 @@ class TenderAdmin(FieldsetsInlineMixin, admin.ModelAdmin): "kind", "deadline_date", "start_working_date", - "siae_count_with_link", - # "siae_email_send_count_with_link", - "siae_email_link_click_count_with_link", - "siae_detail_display_count_with_link", - # "siae_email_link_click_or_detail_display_count_with_link", - "siae_detail_contact_click_count_with_link", + "siae_count_annotated_with_link", + # "siae_email_send_count_annotated_with_link", + "siae_email_link_click_count_annotated_with_link", + "siae_detail_display_count_annotated_with_link", + # "siae_email_link_click_or_detail_display_count_annotated_with_link", + "siae_detail_contact_click_count_annotated_with_link", "siae_transactioned", "created_at", "validated_at", @@ -172,13 +172,13 @@ class TenderAdmin(FieldsetsInlineMixin, admin.ModelAdmin): "survey_transactioned_answer", "survey_transactioned_answer_date", "validated_at", - "question_count_with_link", - "siae_count_with_link", - "siae_email_send_count_with_link", - "siae_email_link_click_count_with_link", - "siae_detail_display_count_with_link", - "siae_email_link_click_or_detail_display_count_with_link", - "siae_detail_contact_click_count_with_link", + "question_count_annotated_with_link", + "siae_count_annotated_with_link", + "siae_email_send_count_annotated_with_link", + "siae_email_link_click_count_annotated_with_link", + "siae_detail_display_count_annotated_with_link", + "siae_email_link_click_or_detail_display_count_annotated_with_link", + "siae_detail_contact_click_count_annotated_with_link", "logs_display", "extra_data_display", "source", @@ -209,7 +209,7 @@ class TenderAdmin(FieldsetsInlineMixin, admin.ModelAdmin): "constraints", "external_link", "accept_cocontracting", - "question_count_with_link", + "question_count_annotated_with_link", ), }, ), @@ -279,12 +279,12 @@ class TenderAdmin(FieldsetsInlineMixin, admin.ModelAdmin): "Structures", { "fields": ( - "siae_count_with_link", - "siae_email_send_count_with_link", - "siae_email_link_click_count_with_link", - "siae_detail_display_count_with_link", - "siae_email_link_click_or_detail_display_count_with_link", - "siae_detail_contact_click_count_with_link", + "siae_count_annotated_with_link", + "siae_email_send_count_annotated_with_link", + "siae_email_link_click_count_annotated_with_link", + "siae_detail_display_count_annotated_with_link", + "siae_email_link_click_or_detail_display_count_annotated_with_link", + "siae_detail_contact_click_count_annotated_with_link", ) }, ), @@ -338,6 +338,7 @@ class TenderAdmin(FieldsetsInlineMixin, admin.ModelAdmin): def get_queryset(self, request): qs = super().get_queryset(request) qs = qs.with_siae_stats() + qs = qs.with_question_stats() return qs def get_changeform_initial_data(self, request): @@ -405,73 +406,73 @@ def user_with_link(self, tender): user_with_link.short_description = "Auteur" user_with_link.admin_order_field = "author" - def question_count_with_link(self, tender): + def question_count_annotated_with_link(self, tender): url = reverse("admin:tenders_tenderquestion_changelist") + f"?tender__in={tender.id}" - return format_html(f'{getattr(tender, "questions_count", 0)}') + return format_html(f'{getattr(tender, "question_count_annotated", 0)}') - question_count_with_link.short_description = TenderQuestion._meta.verbose_name_plural - question_count_with_link.admin_order_field = "questions_count" + question_count_annotated_with_link.short_description = TenderQuestion._meta.verbose_name_plural + question_count_annotated_with_link.admin_order_field = "question_count_annotated" - def siae_count_with_link(self, tender): + def siae_count_annotated_with_link(self, tender): url = reverse("admin:siaes_siae_changelist") + f"?tenders__in={tender.id}" - return format_html(f'{getattr(tender, "siae_count", 0)}') + return format_html(f'{getattr(tender, "siae_count_annotated", 0)}') - siae_count_with_link.short_description = "Structures concernées" - siae_count_with_link.admin_order_field = "siae_count" + siae_count_annotated_with_link.short_description = "Structures concernées" + siae_count_annotated_with_link.admin_order_field = "siae_count_annotated" - def siae_email_send_count_with_link(self, tender): + def siae_email_send_count_annotated_with_link(self, tender): url = ( reverse("admin:siaes_siae_changelist") + f"?tenders__in={tender.id}&tendersiae__email_send_date__isnull=False" ) - return format_html(f'{getattr(tender, "siae_email_send_count", 0)}') + return format_html(f'{getattr(tender, "siae_email_send_count_annotated", 0)}') - siae_email_send_count_with_link.short_description = "S. contactées" - siae_email_send_count_with_link.admin_order_field = "siae_email_send_count" + siae_email_send_count_annotated_with_link.short_description = "S. contactées" + siae_email_send_count_annotated_with_link.admin_order_field = "siae_email_send_count_annotated" - def siae_email_link_click_count_with_link(self, tender): + def siae_email_link_click_count_annotated_with_link(self, tender): url = ( reverse("admin:siaes_siae_changelist") + f"?tenders__in={tender.id}&tendersiae__email_link_click_date__isnull=False" ) - return format_html(f'{getattr(tender, "siae_email_link_click_count", 0)}') + return format_html(f'{getattr(tender, "siae_email_link_click_count_annotated", 0)}') - siae_email_link_click_count_with_link.short_description = "S. cliquées" - siae_email_link_click_count_with_link.admin_order_field = "siae_email_link_click_count" + siae_email_link_click_count_annotated_with_link.short_description = "S. cliquées" + siae_email_link_click_count_annotated_with_link.admin_order_field = "siae_email_link_click_count_annotated" - def siae_detail_display_count_with_link(self, tender): + def siae_detail_display_count_annotated_with_link(self, tender): url = ( reverse("admin:siaes_siae_changelist") + f"?tenders__in={tender.id}&tendersiae__detail_display_date__isnull=False" ) - return format_html(f'{getattr(tender, "siae_detail_display_count", 0)}') + return format_html(f'{getattr(tender, "siae_detail_display_count_annotated", 0)}') - siae_detail_display_count_with_link.short_description = "S. vues" - siae_detail_display_count_with_link.admin_order_field = "siae_detail_display_count" + siae_detail_display_count_annotated_with_link.short_description = "S. vues" + siae_detail_display_count_annotated_with_link.admin_order_field = "siae_detail_display_count_annotated" - def siae_email_link_click_or_detail_display_count_with_link(self, tender): + def siae_email_link_click_or_detail_display_count_annotated_with_link(self, tender): url = ( reverse("admin:siaes_siae_changelist") + f"?tenders__in={tender.id}&tendersiae__detail_display_date__isnull=False" ) return format_html( - f'{getattr(tender, "siae_email_link_click_or_detail_display_count", 0)}' + f'{getattr(tender, "siae_email_link_click_or_detail_display_count_annotated", 0)}' ) - siae_email_link_click_or_detail_display_count_with_link.short_description = "S. cliquées ou vues" - siae_email_link_click_or_detail_display_count_with_link.admin_order_field = ( - "siae_email_link_click_or_detail_display_count" + siae_email_link_click_or_detail_display_count_annotated_with_link.short_description = "S. cliquées ou vues" + siae_email_link_click_or_detail_display_count_annotated_with_link.admin_order_field = ( + "siae_email_link_click_or_detail_display_count_annotated" ) - def siae_detail_contact_click_count_with_link(self, tender): + def siae_detail_contact_click_count_annotated_with_link(self, tender): url = ( reverse("admin:siaes_siae_changelist") + f"?tenders__in={tender.id}&tendersiae__detail_contact_click_date__isnull=False" ) - return format_html(f'{getattr(tender, "siae_detail_contact_click_count", 0)}') + return format_html(f'{getattr(tender, "siae_detail_contact_click_count_annotated", 0)}') - siae_detail_contact_click_count_with_link.short_description = "S. intéressées" - siae_detail_contact_click_count_with_link.admin_order_field = "siae_detail_contact_click_count" + siae_detail_contact_click_count_annotated_with_link.short_description = "S. intéressées" + siae_detail_contact_click_count_annotated_with_link.admin_order_field = "siae_detail_contact_click_count_annotated" def logs_display(self, tender=None): if tender: diff --git a/lemarche/tenders/models.py b/lemarche/tenders/models.py index 0d54e1c46..24e5ee845 100644 --- a/lemarche/tenders/models.py +++ b/lemarche/tenders/models.py @@ -94,30 +94,30 @@ def order_by_deadline_date(self, limit_date=datetime.today()): ) def with_question_stats(self): - return self.annotate(question_count=Count("questions", distinct=True)) + return self.annotate(question_count_annotated=Count("questions", distinct=True)) def with_siae_stats(self): """ Enrich each Tender with stats on their linked Siae """ return self.annotate( - siae_count=Count("siaes", distinct=True), - siae_email_send_count=Sum( + siae_count_annotated=Count("siaes", distinct=True), + siae_email_send_count_annotated=Sum( Case(When(tendersiae__email_send_date__isnull=False, then=1), default=0, output_field=IntegerField()) ), - siae_email_link_click_count=Sum( + siae_email_link_click_count_annotated=Sum( Case( When(tendersiae__email_link_click_date__isnull=False, then=1), default=0, output_field=IntegerField(), ) ), - siae_detail_display_count=Sum( + siae_detail_display_count_annotated=Sum( Case( When(tendersiae__detail_display_date__isnull=False, then=1), default=0, output_field=IntegerField() ) ), - siae_email_link_click_or_detail_display_count=Sum( + siae_email_link_click_or_detail_display_count_annotated=Sum( Case( When( Q(tendersiae__detail_display_date__isnull=False) @@ -128,14 +128,14 @@ def with_siae_stats(self): output_field=IntegerField(), ) ), - siae_detail_contact_click_count=Sum( + siae_detail_contact_click_count_annotated=Sum( Case( When(tendersiae__detail_contact_click_date__isnull=False, then=1), default=0, output_field=IntegerField(), ) ), - siae_detail_contact_click_since_last_seen_date_count=Sum( + siae_detail_contact_click_since_last_seen_date_count_annotated=Sum( Case( When( tendersiae__detail_contact_click_date__gte=Greatest( @@ -151,14 +151,14 @@ def with_siae_stats(self): def with_network_siae_stats(self, network_siaes): return self.annotate( - network_siae_email_send_count=Sum( + network_siae_email_send_count_annotated=Sum( Case( When(Q(tendersiae__email_send_date__isnull=False) & Q(tendersiae__siae__in=network_siaes), then=1), default=0, output_field=IntegerField(), ), ), - network_siae_detail_contact_click_count=Sum( + network_siae_detail_contact_click_count_annotated=Sum( Case( When( Q(tendersiae__detail_contact_click_date__isnull=False) & Q(tendersiae__siae__in=network_siaes), @@ -496,10 +496,6 @@ def location_display(self) -> str: def questions_list(self): return list(self.questions.values("id", "text")) - @property - def questions_count(self): - return self.questions.count() - @cached_property def external_link_title(self) -> str: if self.kind == tender_constants.KIND_TENDER: diff --git a/lemarche/tenders/tests.py b/lemarche/tenders/tests.py index e5cae942f..2060a583a 100644 --- a/lemarche/tenders/tests.py +++ b/lemarche/tenders/tests.py @@ -9,6 +9,7 @@ from django.test import RequestFactory, TestCase from django.utils import timezone +from lemarche.networks.factories import NetworkFactory from lemarche.perimeters.factories import PerimeterFactory from lemarche.perimeters.models import Perimeter from lemarche.sectors.factories import SectorFactory, SectorGroupFactory @@ -316,50 +317,50 @@ def test_with_siae_stats(self): self.assertEqual(Tender.objects.count(), 2 + 1) tender_with_siae_1 = Tender.objects.with_siae_stats().filter(id=self.tender_with_siae_1.id).first() self.assertEqual(tender_with_siae_1.siaes.count(), 6) - self.assertEqual(tender_with_siae_1.siae_count, 6) - self.assertEqual(tender_with_siae_1.siae_email_send_count, 4) - self.assertEqual(tender_with_siae_1.siae_email_link_click_count, 3) - self.assertEqual(tender_with_siae_1.siae_detail_display_count, 2) - self.assertEqual(tender_with_siae_1.siae_email_link_click_or_detail_display_count, 2) - self.assertEqual(tender_with_siae_1.siae_detail_contact_click_count, 1) - self.assertEqual(tender_with_siae_1.siae_detail_contact_click_since_last_seen_date_count, 1) + self.assertEqual(tender_with_siae_1.siae_count_annotated, 6) + self.assertEqual(tender_with_siae_1.siae_email_send_count_annotated, 4) + self.assertEqual(tender_with_siae_1.siae_email_link_click_count_annotated, 3) + self.assertEqual(tender_with_siae_1.siae_detail_display_count_annotated, 2) + self.assertEqual(tender_with_siae_1.siae_email_link_click_or_detail_display_count_annotated, 2) + self.assertEqual(tender_with_siae_1.siae_detail_contact_click_count_annotated, 1) + self.assertEqual(tender_with_siae_1.siae_detail_contact_click_since_last_seen_date_count_annotated, 1) tender_with_siae_2 = Tender.objects.with_siae_stats().filter(id=self.tender_with_siae_2.id).first() self.assertEqual(tender_with_siae_2.siaes.count(), 1) - self.assertEqual(tender_with_siae_2.siae_count, 1) - self.assertEqual(tender_with_siae_2.siae_email_send_count, 1) - self.assertEqual(tender_with_siae_2.siae_detail_display_count, 1) - self.assertEqual(tender_with_siae_2.siae_email_link_click_or_detail_display_count, 1) - self.assertEqual(tender_with_siae_2.siae_detail_contact_click_count, 1) - self.assertEqual(tender_with_siae_2.siae_detail_contact_click_since_last_seen_date_count, 1) + self.assertEqual(tender_with_siae_2.siae_count_annotated, 1) + self.assertEqual(tender_with_siae_2.siae_email_send_count_annotated, 1) + self.assertEqual(tender_with_siae_2.siae_detail_display_count_annotated, 1) + self.assertEqual(tender_with_siae_2.siae_email_link_click_or_detail_display_count_annotated, 1) + self.assertEqual(tender_with_siae_2.siae_detail_contact_click_count_annotated, 1) + self.assertEqual(tender_with_siae_2.siae_detail_contact_click_since_last_seen_date_count_annotated, 1) tender_without_siae = Tender.objects.with_siae_stats().filter(id=self.tender_without_siae.id).first() self.assertEqual(tender_without_siae.siaes.count(), 0) - self.assertEqual(tender_without_siae.siae_count, 0) - self.assertEqual(tender_without_siae.siae_email_send_count, 0) - self.assertEqual(tender_without_siae.siae_detail_display_count, 0) - self.assertEqual(tender_without_siae.siae_email_link_click_or_detail_display_count, 0) - self.assertEqual(tender_without_siae.siae_detail_contact_click_count, 0) - self.assertEqual(tender_without_siae.siae_detail_contact_click_since_last_seen_date_count, 0) + self.assertEqual(tender_without_siae.siae_count_annotated, 0) + self.assertEqual(tender_without_siae.siae_email_send_count_annotated, 0) + self.assertEqual(tender_without_siae.siae_detail_display_count_annotated, 0) + self.assertEqual(tender_without_siae.siae_email_link_click_or_detail_display_count_annotated, 0) + self.assertEqual(tender_without_siae.siae_detail_contact_click_count_annotated, 0) + self.assertEqual(tender_without_siae.siae_detail_contact_click_since_last_seen_date_count_annotated, 0) def test_siae_with_tender_stats(self): self.assertEqual(Siae.objects.count(), 6 + 1) siae_with_tender_1 = Siae.objects.with_tender_stats().filter(id=self.siae_with_tender_1.id).first() # self.assertEqual(siae_with_tender_1.tenders.count(), 2) - self.assertEqual(siae_with_tender_1.tender_count, 2) - self.assertEqual(siae_with_tender_1.tender_email_send_count, 1) - self.assertEqual(siae_with_tender_1.tender_detail_display_count, 1) - self.assertEqual(siae_with_tender_1.tender_detail_contact_click_count, 1) + self.assertEqual(siae_with_tender_1.tender_count_annotated, 2) + self.assertEqual(siae_with_tender_1.tender_email_send_count_annotated, 1) + self.assertEqual(siae_with_tender_1.tender_detail_display_count_annotated, 1) + self.assertEqual(siae_with_tender_1.tender_detail_contact_click_count_annotated, 1) siae_without_tender = Siae.objects.with_tender_stats().filter(id=self.siae_without_tender.id).first() self.assertEqual(siae_without_tender.tenders.count(), 0) - self.assertEqual(siae_without_tender.tender_count, 0) - self.assertEqual(siae_without_tender.tender_email_send_count, 0) - self.assertEqual(siae_without_tender.tender_detail_display_count, 0) - self.assertEqual(siae_without_tender.tender_detail_contact_click_count, 0) + self.assertEqual(siae_without_tender.tender_count_annotated, 0) + self.assertEqual(siae_without_tender.tender_email_send_count_annotated, 0) + self.assertEqual(siae_without_tender.tender_detail_display_count_annotated, 0) + self.assertEqual(siae_without_tender.tender_detail_contact_click_count_annotated, 0) def test_with_question_stats(self): self.assertEqual(TenderQuestion.objects.count(), 2) tender_with_siae_1 = Tender.objects.with_question_stats().filter(id=self.tender_with_siae_1.id).first() self.assertEqual(tender_with_siae_1.questions.count(), 2) - self.assertEqual(tender_with_siae_1.question_count, 2) + self.assertEqual(tender_with_siae_1.question_count_annotated, 2) def test_with_deadline_date_is_outdated(self): TenderFactory(deadline_date=date_last_week) @@ -370,19 +371,29 @@ def test_with_deadline_date_is_outdated(self): self.assertEqual(tender_with_siae_1.id, self.tender_with_siae_1.id) self.assertFalse(tender_with_siae_1.deadline_date_is_outdated_annotated) + def test_with_network_siae_stats(self): + network_with_siaes = NetworkFactory(siaes=[self.siae_with_tender_1, self.siae_without_tender]) + tender_with_siae_2 = ( + Tender.objects.with_network_siae_stats(network_with_siaes.siaes.all()) + .filter(id=self.tender_with_siae_2.id) + .first() + ) + self.assertEqual(tender_with_siae_2.network_siae_email_send_count_annotated, 1) + self.assertEqual(tender_with_siae_2.network_siae_detail_contact_click_count_annotated, 1) + # doesn't work when chaining these 2 querysets: adds duplicates... # def test_chain_querysets(self): # tender_with_siae_1 = ( # Tender.objects.with_question_stats().with_siae_stats().filter(id=self.tender_with_siae_1.id).first() # ) # self.assertEqual(tender_with_siae_1.siaes.count(), 6) - # self.assertEqual(tender_with_siae_1.siae_count, 6) - # self.assertEqual(tender_with_siae_1.siae_email_send_count, 4) - # self.assertEqual(tender_with_siae_1.siae_email_link_click_count, 3) - # self.assertEqual(tender_with_siae_1.siae_detail_display_count, 2) - # self.assertEqual(tender_with_siae_1.siae_email_link_click_or_detail_display_count, 2) - # self.assertEqual(tender_with_siae_1.siae_detail_contact_click_count, 1) - # self.assertEqual(tender_with_siae_1.siae_detail_contact_click_since_last_seen_date_count, 1) + # self.assertEqual(tender_with_siae_1.siae_count_annotated, 6) + # self.assertEqual(tender_with_siae_1.siae_email_send_count_annotated, 4) + # self.assertEqual(tender_with_siae_1.siae_email_link_click_count_annotated, 3) + # self.assertEqual(tender_with_siae_1.siae_detail_display_count_annotated, 2) + # self.assertEqual(tender_with_siae_1.siae_email_link_click_or_detail_display_count_annotated, 2) + # self.assertEqual(tender_with_siae_1.siae_detail_contact_click_count_annotated, 1) + # self.assertEqual(tender_with_siae_1.siae_detail_contact_click_since_last_seen_date_count_annotated, 1) class TenderMigrationToSelectTest(TestCase): @@ -652,9 +663,9 @@ def test_edit_form_matching_on_submission(self): ) tender_response = response.context_data["adminform"].form.instance self.assertEqual(tender_response.id, self.tender.id) - self.assertEqual(hasattr(tender_response, "siae_count"), True) - self.assertEqual(tender_response.siae_count, 2) - self.assertEqual(tender_response.siae_count, self.tender.tendersiae_set.count()) + self.assertEqual(hasattr(tender_response, "siae_count_annotated"), True) + self.assertEqual(tender_response.siae_count_annotated, 2) + self.assertEqual(tender_response.siae_count_annotated, self.tender.tendersiae_set.count()) # update sectors to have only one match for siaes response = self.client.post( tender_update_post_url, @@ -666,7 +677,7 @@ def test_edit_form_matching_on_submission(self): follow=True, ) tender_response = response.context_data["adminform"].form.instance - self.assertEqual(tender_response.siae_count, 1) + self.assertEqual(tender_response.siae_count_annotated, 1) tender_siae_matched = tender_response.tendersiae_set.first() # only one siae # update for another sectors and check if siaes are not the same response = self.client.post( @@ -678,6 +689,6 @@ def test_edit_form_matching_on_submission(self): follow=True, ) tender_response = response.context_data["adminform"].form.instance - self.assertEqual(tender_response.siae_count, 1) + self.assertEqual(tender_response.siae_count_annotated, 1) tender_siae_matched_2 = tender_response.tendersiae_set.first() # only one siae self.assertNotEqual(tender_siae_matched.pk, tender_siae_matched_2.pk) diff --git a/lemarche/www/dashboard_networks/views.py b/lemarche/www/dashboard_networks/views.py index ab70a1bd6..5cbf03120 100644 --- a/lemarche/www/dashboard_networks/views.py +++ b/lemarche/www/dashboard_networks/views.py @@ -26,7 +26,7 @@ def get_queryset(self): qs = super().get_queryset() # first get the network's siaes self.network = Network.objects.get(slug=self.kwargs.get("slug")) - qs = qs.filter(networks__in=[self.network]).with_tender_stats().annotate_with_brand_or_name(with_order_by=True) + qs = qs.filter(networks__in=[self.network]).with_tender_stats().with_brand_or_name(with_order_by=True) # then filter with the form self.filter_form = NetworkSiaeFilterForm(data=self.request.GET) qs = self.filter_form.filter_queryset(qs) diff --git a/lemarche/www/dashboard_siaes/views.py b/lemarche/www/dashboard_siaes/views.py index a44cb05d1..24771a913 100644 --- a/lemarche/www/dashboard_siaes/views.py +++ b/lemarche/www/dashboard_siaes/views.py @@ -143,9 +143,9 @@ def get_context_data(self, **kwargs): context["label_formset"] = SiaeLabelOldFormSet(self.request.POST, instance=self.object) else: context["label_formset"] = SiaeLabelOldFormSet(instance=self.object) - context["last_3_siae_content_filled_full"] = ( + context["last_3_siae_content_filled_full_annotated"] = ( Siae.objects.with_content_filled_stats() - .filter(content_filled_full=True) + .filter(content_filled_full_annotated=True) .exclude(id=self.object.id) .order_by("-updated_at")[:3] ) diff --git a/lemarche/www/siaes/forms.py b/lemarche/www/siaes/forms.py index a06a64d5a..290c55f0f 100644 --- a/lemarche/www/siaes/forms.py +++ b/lemarche/www/siaes/forms.py @@ -276,10 +276,10 @@ def filter_queryset(self, qs=None): # noqa C901 lower_limit, upper_limit = employees.split("-") # Check lower limitation, it always exists when employees filter is used - qs = qs.with_employees_count().filter( - (Q(employees_count__isnull=False) & Q(employees_count__gte=int(lower_limit))) + qs = qs.with_employees_stats().filter( + (Q(employees_count_annotated__isnull=False) & Q(employees_count_annotated__gte=int(lower_limit))) | ( - Q(employees_count=None) + Q(employees_count_annotated=None) & Q(api_entreprise_employees__in=EMPLOYEES_API_ENTREPRISE_MAPPING[employees]) ) ) @@ -287,9 +287,9 @@ def filter_queryset(self, qs=None): # noqa C901 # Upper limitation if upper_limit: qs = qs.filter( - (Q(employees_count__isnull=False) & Q(employees_count__lte=int(upper_limit))) + (Q(employees_count_annotated__isnull=False) & Q(employees_count_annotated__lte=int(upper_limit))) | ( - Q(employees_count=None) + Q(employees_count_annotated=None) & Q(api_entreprise_employees__in=EMPLOYEES_API_ENTREPRISE_MAPPING[employees]) ) ) diff --git a/lemarche/www/siaes/views.py b/lemarche/www/siaes/views.py index 717507b3d..b02b39e15 100644 --- a/lemarche/www/siaes/views.py +++ b/lemarche/www/siaes/views.py @@ -68,7 +68,7 @@ def get_queryset(self): results = filter_form.filter_queryset() results_ordered = filter_form.order_queryset(results) if user.is_authenticated: - results_ordered = results_ordered.annotate_with_user_favorite_list_count(user) + results_ordered = results_ordered.with_in_user_favorite_list_stats(user) return results_ordered def get_mailto_share_url(self): @@ -262,7 +262,7 @@ def get_queryset(self): """ qs = super().get_queryset() if self.request.user.is_authenticated: - qs = qs.annotate_with_user_favorite_list_count(self.request.user) + qs = qs.with_in_user_favorite_list_stats(self.request.user) return qs def get_context_data(self, **kwargs):