From 7ab2f2aee14b91a84dd2d02906bf03e7e98c668c Mon Sep 17 00:00:00 2001 From: SebastienReuiller Date: Thu, 5 Dec 2024 09:54:17 +0100 Subject: [PATCH] =?UTF-8?q?fix(Secteurs=20d'activit=C3=A9s):=20Mise=20?= =?UTF-8?q?=C3=A0=20jour=20du=20calcul=20du=20nombre=20de=20secteurs=20pou?= =?UTF-8?q?r=20le=20d=C3=A9duire=20des=20activit=C3=A9s=20associ=C3=A9es?= =?UTF-8?q?=20(#1564)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../commands/update_siae_count_fields.py | 2 +- lemarche/siaes/models.py | 25 +++--- lemarche/siaes/tests/test_commands.py | 77 ++++++++++++++++++- lemarche/siaes/tests/test_models.py | 18 ++--- .../templates/dashboard/siae_edit_base.html | 2 +- lemarche/utils/export.py | 2 +- 6 files changed, 99 insertions(+), 27 deletions(-) diff --git a/lemarche/siaes/management/commands/update_siae_count_fields.py b/lemarche/siaes/management/commands/update_siae_count_fields.py index f09c263e1..3590a31c7 100644 --- a/lemarche/siaes/management/commands/update_siae_count_fields.py +++ b/lemarche/siaes/management/commands/update_siae_count_fields.py @@ -47,7 +47,7 @@ def handle(self, *args, **options): for index, siae in enumerate(siae_queryset): # M2M siae.user_count = siae.users.count() - siae.sector_count = siae.sectors.count() + siae.sector_count = siae.activities.values_list("sector_group").distinct().count() siae.network_count = siae.networks.count() siae.group_count = siae.groups.count() # FK diff --git a/lemarche/siaes/models.py b/lemarche/siaes/models.py index 0e1b508ee..bd5ff0fc2 100644 --- a/lemarche/siaes/models.py +++ b/lemarche/siaes/models.py @@ -1227,15 +1227,16 @@ def elasticsearch_index_metadata(self): return metadata - def sectors_list_string(self, display_max=3): - sectors_name_list = self.sectors.form_filter_queryset().values_list("name", flat=True) + def sector_groups_list_string(self, display_max=3): + # Retrieve sectors from activities instead of directly from the sectors field + sectors_name_list = set(self.activities.values_list("sector_group__name", flat=True)) if display_max and len(sectors_name_list) > display_max: sectors_name_list = sectors_name_list[:display_max] sectors_name_list.append("…") return ", ".join(sectors_name_list) - def sectors_full_list_string(self): - return self.sectors_list_string(display_max=None) + def sector_groups_full_list_string(self): + return self.sector_groups_list_string(display_max=None) @cached_property def stat_view_count_last_3_months(self): @@ -1307,14 +1308,6 @@ def siae_users_changed(sender, instance, action, **kwargs): instance.save() -@receiver(m2m_changed, sender=Siae.sectors.through) -def siae_sectors_changed(sender, instance, action, **kwargs): - if isinstance(instance, Siae): - if action in ("post_add", "post_remove", "post_clear"): - instance.sector_count = instance.sectors.count() - instance.save() - - @receiver(m2m_changed, sender=Siae.networks.through) def siae_networks_changed(sender, instance, action, **kwargs): if isinstance(instance, Siae): @@ -1614,6 +1607,14 @@ def __str__(self): return self.name +@receiver(post_save, sender=SiaeActivity) +@receiver(post_delete, sender=SiaeActivity) +def siae_activity_post_save(sender, instance, **kwargs): + """Update sector_count when SiaeActivity is created or updated.""" + instance.siae.sector_count = instance.siae.activities.values("sector_group").distinct().count() + instance.siae.save() + + class SiaeClientReference(models.Model): name = models.CharField(verbose_name="Nom", max_length=255, blank=True) description = models.TextField(verbose_name="Description", blank=True) diff --git a/lemarche/siaes/tests/test_commands.py b/lemarche/siaes/tests/test_commands.py index 1da10b327..60c7acd86 100644 --- a/lemarche/siaes/tests/test_commands.py +++ b/lemarche/siaes/tests/test_commands.py @@ -1,12 +1,15 @@ +import factory from django.core.management import call_command +from django.db.models import signals from django.test import TransactionTestCase from lemarche.perimeters.factories import PerimeterFactory from lemarche.perimeters.models import Perimeter from lemarche.sectors.factories import SectorFactory from lemarche.siaes import constants as siae_constants -from lemarche.siaes.factories import SiaeFactory +from lemarche.siaes.factories import SiaeActivityFactory, SiaeFactory from lemarche.siaes.models import SiaeActivity +from lemarche.users.factories import UserFactory class SiaeActivitiesCreateCommandTest(TransactionTestCase): @@ -153,3 +156,75 @@ def test_create_activities(self): self.assertEqual(siae5_activities.first().presta_type, [siae_constants.PRESTA_DISP]) self.assertEqual(siae5_activities.first().geo_range, siae_constants.GEO_RANGE_ZONES) self.assertEqual(siae5_activities.first().locations.count(), 0) + + +class SiaeUpdateCountFieldsCommandTest(TransactionTestCase): + @factory.django.mute_signals(signals.post_save, signals.m2m_changed) + def test_update_count_fields(self): + """ + Create two siaes with users and activities, and check that the count fields are updated correctly + """ + siae_1 = SiaeFactory() + for _ in range(3): + user = UserFactory() + siae_1.users.add(user) + SiaeActivityFactory.create_batch(2, siae=siae_1) + + self.assertEqual(siae_1.user_count, 0) + self.assertEqual(siae_1.sector_count, 0) + self.assertEqual(siae_1.network_count, 0) + self.assertEqual(siae_1.group_count, 0) + self.assertEqual(siae_1.offer_count, 0) + self.assertEqual(siae_1.client_reference_count, 0) + self.assertEqual(siae_1.label_count, 0) + self.assertEqual(siae_1.image_count, 0) + self.assertEqual(siae_1.etablissement_count, 0) + self.assertEqual(siae_1.completion_rate, None) + self.assertEqual(siae_1.tender_count, 0) + self.assertEqual(siae_1.tender_email_send_count, 0) + self.assertEqual(siae_1.tender_email_link_click_count, 0) + self.assertEqual(siae_1.tender_detail_display_count, 0) + self.assertEqual(siae_1.tender_detail_contact_click_count, 0) + + siae_2 = SiaeFactory() + for _ in range(2): + user = UserFactory() + siae_2.users.add(user) + SiaeActivityFactory.create_batch(4, siae=siae_2) + + self.assertEqual(siae_2.user_count, 0) + self.assertEqual(siae_2.sector_count, 0) + + call_command("update_siae_count_fields") + siae_1.refresh_from_db() + self.assertEqual(siae_1.user_count, 3) + self.assertEqual(siae_1.sector_count, 2) + siae_2.refresh_from_db() + self.assertEqual(siae_2.user_count, 2) + self.assertEqual(siae_2.sector_count, 4) + + @factory.django.mute_signals(signals.post_save, signals.m2m_changed) + def test_update_count_fields_with_id(self): + """ + Create two siaes with users and activities, and check that the count fields are updated correctly + Only for the siae with id + """ + siae_to_update = SiaeFactory() + for _ in range(3): + user = UserFactory() + siae_to_update.users.add(user) + SiaeActivityFactory.create_batch(2, siae=siae_to_update) + + siae_not_updated = SiaeFactory() + for _ in range(3): + user = UserFactory() + siae_not_updated.users.add(user) + SiaeActivityFactory.create_batch(2, siae=siae_not_updated) + + call_command("update_siae_count_fields", id=siae_to_update.id) + siae_to_update.refresh_from_db() + self.assertEqual(siae_to_update.user_count, 3) + self.assertEqual(siae_to_update.sector_count, 2) + siae_not_updated.refresh_from_db() + self.assertEqual(siae_not_updated.user_count, 0) + self.assertEqual(siae_not_updated.sector_count, 0) diff --git a/lemarche/siaes/tests/test_models.py b/lemarche/siaes/tests/test_models.py index 506664c51..fb2fe0eaa 100644 --- a/lemarche/siaes/tests/test_models.py +++ b/lemarche/siaes/tests/test_models.py @@ -5,9 +5,9 @@ from lemarche.networks.factories import NetworkFactory from lemarche.perimeters.factories import PerimeterFactory 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 ( + SiaeActivityFactory, SiaeClientReferenceFactory, SiaeFactory, SiaeGroupFactory, @@ -171,8 +171,7 @@ def test_is_missing_content_property(self): ) self.assertTrue(score_completion_before < siae_full.completion_rate_calculated) score_completion_before = siae_full.completion_rate_calculated - sector = SectorFactory() - siae_full.sectors.add(sector) + SiaeActivityFactory(siae=siae_full) SiaeOfferFactory(siae=siae_full) SiaeLabelOldFactory(siae=siae_full) siae_full.save() # to update stats @@ -186,7 +185,7 @@ def test_is_missing_content_property(self): # contact_phone="0000000000", description="test", ) - siae_full_2.sectors.add(sector) + SiaeActivityFactory(siae=siae_full_2) SiaeOfferFactory(siae=siae_full_2) SiaeLabelOldFactory(siae=siae_full_2) siae_full_2.save() # to update stats @@ -265,13 +264,11 @@ def test_update_related_offer_count_on_save(self): siae.save() self.assertEqual(siae.offer_count, 1) - def test_update_m2m_sector_count_on_save(self): + def test_update_o2m_sector_count_on_save(self): siae = SiaeFactory() - sector = SectorFactory() self.assertEqual(siae.sector_count, 0) - siae.sectors.add(sector) - self.assertEqual(siae.sectors.count(), 1) - # siae.save() # no need to run save(), m2m_changed signal was triggered above + SiaeActivityFactory(siae=siae) + self.assertEqual(siae.activities.count(), 1) self.assertEqual(siae.sector_count, 1) def test_update_m2m_network_count_on_save(self): @@ -328,8 +325,7 @@ def test_update_content_fill_date_on_save(self): siae = SiaeFactory(description="") user = UserFactory() siae.users.add(user) - sector = SectorFactory() - siae.sectors.add(sector) + SiaeActivityFactory(siae=siae) self.assertIsNone(siae.content_filled_basic_date) siae.description = "test" siae.save() diff --git a/lemarche/templates/dashboard/siae_edit_base.html b/lemarche/templates/dashboard/siae_edit_base.html index 4bc0e9242..0418a8573 100644 --- a/lemarche/templates/dashboard/siae_edit_base.html +++ b/lemarche/templates/dashboard/siae_edit_base.html @@ -37,7 +37,7 @@

Votre fiche n'est pas complète, et donc moins visib
    {% if not siae.sector_count %}
  1. - Ajoutez un ou plusieurs secteurs d'activité + Ajoutez un ou plusieurs secteurs d'activité
  2. {% endif %} {% if not siae.description and not siae.logo_url %} diff --git a/lemarche/utils/export.py b/lemarche/utils/export.py index 556eeda07..8e705ac78 100644 --- a/lemarche/utils/export.py +++ b/lemarche/utils/export.py @@ -68,7 +68,7 @@ def generate_siae_row(siae: Siae, siae_field_list): col_value = "Oui" if getattr(siae, field_name, None) else "Non" # ManyToManyFields elif field_name == "sectors": - col_value = siae.sectors_full_list_string() + col_value = siae.sector_groups_full_list_string() # Complex fields elif field_name == "contact_phone": col_value = siae.contact_phone_display