From a775ccf13de5071aa622c9ab8b79c6d67bb1ddc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Reuiller?= Date: Fri, 21 Jun 2024 18:30:46 +0200 Subject: [PATCH] tender update survey --- .../templates/tenders/create_step_survey.html | 2 +- lemarche/tenders/admin.py | 2 +- lemarche/tenders/constants.py | 34 +++++++++++++ ...le_marche_doesnt_exist_how_to_find_siae.py | 48 +++++++++++++++++++ lemarche/tenders/models.py | 7 +++ lemarche/www/pages/views.py | 7 +-- lemarche/www/tenders/forms.py | 22 ++------- lemarche/www/tenders/tests.py | 9 +++- lemarche/www/tenders/views.py | 34 ++++++------- 9 files changed, 118 insertions(+), 47 deletions(-) create mode 100644 lemarche/tenders/migrations/0089_tender_le_marche_doesnt_exist_how_to_find_siae.py diff --git a/lemarche/templates/tenders/create_step_survey.html b/lemarche/templates/tenders/create_step_survey.html index 18493200e..63d575f7a 100644 --- a/lemarche/templates/tenders/create_step_survey.html +++ b/lemarche/templates/tenders/create_step_survey.html @@ -29,7 +29,7 @@
- {% bootstrap_field form.le_marche_doesnt_exist_how_to_find_siae form_group_class="form-group" %} + {% bootstrap_field form.le_marche_doesnt_exist_how_to_find_siae form_group_class="form-group mb-lg-5" %}
diff --git a/lemarche/tenders/admin.py b/lemarche/tenders/admin.py index 31472276b..50effb560 100644 --- a/lemarche/tenders/admin.py +++ b/lemarche/tenders/admin.py @@ -476,7 +476,7 @@ class TenderAdmin(FieldsetsInlineMixin, admin.ModelAdmin): ), ( "Utilité du marché de l'inclusion", - {"fields": ("scale_marche_useless",)}, + {"fields": ("scale_marche_useless", "le_marche_doesnt_exist_how_to_find_siae")}, ), ( "Status", diff --git a/lemarche/tenders/constants.py b/lemarche/tenders/constants.py index a8f1c3f5a..f1c1a746a 100644 --- a/lemarche/tenders/constants.py +++ b/lemarche/tenders/constants.py @@ -180,6 +180,40 @@ (SURVEY_SCALE_QUESTION_3, "Oui"), ) +SURVEY_DOESNT_EXIST_QUESTION_DONT_KNOW = "i-dont-know" +SURVEY_DOESNT_EXIST_QUESTION_INTERNET_SEARCH = "internet-search" +SURVEY_DOESNT_EXIST_QUESTION_NETWORKS = "networks" +SURVEY_DOESNT_EXIST_QUESTION_DIRECTORY = "directory" +SURVEY_DOESNT_EXIST_QUESTION_RECOMMENDATIONS = "recommendations" +SURVEY_DOESNT_EXIST_QUESTION_KNOWN_PROVIDERS = "known-providers" +SURVEY_DOESNT_EXIST_QUESTION_PUBLIC_TENDERS = "public-tenders" +SURVEY_DOESNT_EXIST_QUESTION_FACILITATORS = "facilitators" +SURVEY_DOESNT_EXIST_QUESTION_LOCAL_SOURCING = "local-sourcing" + +SURVEY_DOESNT_EXIST_QUESTION_CHOICES = ( + (SURVEY_DOESNT_EXIST_QUESTION_DONT_KNOW, "Je ne sais pas"), + ( + SURVEY_DOESNT_EXIST_QUESTION_INTERNET_SEARCH, + "Recherche sur Internet (Google, page jaune, recherche sur le web)", + ), + (SURVEY_DOESNT_EXIST_QUESTION_NETWORKS, "Réseaux professionnels et partenariats"), + (SURVEY_DOESNT_EXIST_QUESTION_DIRECTORY, "Annuaire spécialisé (GESAT, UNEA, Handeco)"), + ( + SURVEY_DOESNT_EXIST_QUESTION_RECOMMENDATIONS, + "Recommandations et bouche-à-oreille (Réseaux sociaux, recommandations personnelles, collègues)", + ), + (SURVEY_DOESNT_EXIST_QUESTION_KNOWN_PROVIDERS, "Prestataires connus et habituels (Fournisseurs actuels)"), + ( + SURVEY_DOESNT_EXIST_QUESTION_PUBLIC_TENDERS, + "Appel d'offres et consultations publiques (BOAMP, JOUE, AWS, appels d'offres)", + ), + (SURVEY_DOESNT_EXIST_QUESTION_FACILITATORS, "Facilitateurs de clauses sociales"), + ( + SURVEY_DOESNT_EXIST_QUESTION_LOCAL_SOURCING, + "Sourcing local et salons professionnels (Recherche locale, salons, événements professionnels)", + ), +) + # survey choices SURVEY_YES_NO_DONT_KNOW_CHOICES = ( (constants.NO, "Non"), diff --git a/lemarche/tenders/migrations/0089_tender_le_marche_doesnt_exist_how_to_find_siae.py b/lemarche/tenders/migrations/0089_tender_le_marche_doesnt_exist_how_to_find_siae.py new file mode 100644 index 000000000..09961c350 --- /dev/null +++ b/lemarche/tenders/migrations/0089_tender_le_marche_doesnt_exist_how_to_find_siae.py @@ -0,0 +1,48 @@ +# Generated by Django 4.2.13 on 2024-06-21 15:15 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("tenders", "0088_alter_tender_contact_phone"), + ] + + operations = [ + migrations.AddField( + model_name="tender", + name="le_marche_doesnt_exist_how_to_find_siae", + field=models.CharField( + choices=[ + ("i-dont-know", "Je ne sais pas"), + ("internet-search", "Recherche sur Internet (Google, page jaune, recherche sur le web)"), + ("networks", "Réseaux professionnels et partenariats"), + ("directory", "Annuaire spécialisé (GESAT, UNEA, Handeco)"), + ( + "recommendations", + ( + "Recommandations et bouche-à-oreille (Réseaux sociaux, recommandations personnelles," + " collègues)" + ), + ), + ("known-providers", "Prestataires connus et habituels (Fournisseurs actuels)"), + ( + "public-tenders", + "Appel d'offres et consultations publiques (BOAMP, JOUE, AWS, appels d'offres)", + ), + ("facilitators", "Facilitateurs de clauses sociales"), + ( + "local-sourcing", + ( + "Sourcing local et salons professionnels (Recherche locale, salons, événements" + " professionnels)" + ), + ), + ], + default="i-dont-know", + help_text="Comment auriez-vous fait pour consulter des prestataires inclusifs ?", + max_length=15, + verbose_name="Sans le marché de l'inclusion", + ), + ), + ] diff --git a/lemarche/tenders/models.py b/lemarche/tenders/models.py index 2965c112c..6076e49b2 100644 --- a/lemarche/tenders/models.py +++ b/lemarche/tenders/models.py @@ -531,6 +531,13 @@ class Tender(models.Model): choices=tender_constants.SURVEY_SCALE_QUESTION_CHOICES, default=tender_constants.SURVEY_SCALE_QUESTION_0, ) + le_marche_doesnt_exist_how_to_find_siae = models.CharField( + verbose_name="Sans le marché de l'inclusion", + help_text="Comment auriez-vous fait pour consulter des prestataires inclusifs ?", + max_length=15, + choices=tender_constants.SURVEY_DOESNT_EXIST_QUESTION_CHOICES, + default=tender_constants.SURVEY_DOESNT_EXIST_QUESTION_DONT_KNOW, + ) marche_benefits = ChoiceArrayField( verbose_name="Bénéfices du marché de l'inclusion", diff --git a/lemarche/www/pages/views.py b/lemarche/www/pages/views.py index 9c4edb61b..29f01a3cb 100644 --- a/lemarche/www/pages/views.py +++ b/lemarche/www/pages/views.py @@ -295,7 +295,6 @@ def csrf_failure(request, reason=""): # noqa C901 ) tender_published_at = None if request.POST.get("is_draft") else timezone.now() tender_dict = dict( - extra_data={}, status=tender_status, published_at=tender_published_at, source=tender_constants.SOURCE_FORM_CSRF, @@ -308,17 +307,13 @@ def csrf_failure(request, reason=""): # noqa C901 if not key.startswith(("csrfmiddlewaretoken", "tender_create_multi_step_view")): value = formtools_session_step_data.get(step).get(key) key_cleaned = key.replace(f"{step}-", "") - if key_cleaned == "le_marche_doesnt_exist_how_to_find_siae": - tender_dict["extra_data"] |= {key_cleaned: value[0]} - elif key_cleaned == "location": + if key_cleaned == "location": tender_dict[key_cleaned] = Perimeter.objects.get(slug=value[0]) - elif key_cleaned in [ "is_country_area", "accept_share_amount", ]: tender_dict[key_cleaned] = value[0] == "on" - elif key_cleaned == "sectors": tender_dict[key_cleaned] = Sector.objects.filter(slug__in=value) elif key_cleaned == "questions_list" and value: diff --git a/lemarche/www/tenders/forms.py b/lemarche/www/tenders/forms.py index e0afd9ba3..af2859ae2 100644 --- a/lemarche/www/tenders/forms.py +++ b/lemarche/www/tenders/forms.py @@ -262,10 +262,10 @@ class TenderCreateStepSurveyForm(forms.ModelForm): required=True, ) - le_marche_doesnt_exist_how_to_find_siae = forms.CharField( - label="Si le Marché de l'inclusion n'existait pas, comment auriez-vous fait pour trouver un prestataire inclusif ?", # noqa + le_marche_doesnt_exist_how_to_find_siae = forms.ChoiceField( + label=Tender._meta.get_field("le_marche_doesnt_exist_how_to_find_siae").help_text, + choices=tender_constants.SURVEY_DOESNT_EXIST_QUESTION_CHOICES, required=False, - widget=forms.Textarea(attrs={"rows": 2, "cols": 15, "data-expandable": "true"}), ) class Meta: @@ -276,23 +276,9 @@ class Meta: def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - if self.instance.id: - self.initial["le_marche_doesnt_exist_how_to_find_siae"] = self.instance.extra_data.get( - "le_marche_doesnt_exist_how_to_find_siae" - ) - else: + if not self.instance.id: self.initial["scale_marche_useless"] = None - def clean(self) -> dict[str, any]: - if not self.errors: - super_cleaned_data = super().clean() - if super_cleaned_data: - cleaned_data = { - "scale_marche_useless": super_cleaned_data.pop("scale_marche_useless"), - "extra_data": super_cleaned_data, - } - return cleaned_data - class TenderCreateStepConfirmationForm(forms.Form): pass diff --git a/lemarche/www/tenders/tests.py b/lemarche/www/tenders/tests.py index 29152d7e0..117ca1e00 100644 --- a/lemarche/www/tenders/tests.py +++ b/lemarche/www/tenders/tests.py @@ -68,7 +68,7 @@ def _generate_fake_data_form( step_4 = { "tender_create_multi_step_view-current_step": "survey", "survey-scale_marche_useless": tender_constants.SURVEY_SCALE_QUESTION_0, - "survey-le_marche_doesnt_exist_how_to_find_siae": "TEST", + "survey-le_marche_doesnt_exist_how_to_find_siae": tender_constants.SURVEY_DOESNT_EXIST_QUESTION_INTERNET_SEARCH, # noqa E501 } | _step_4 step_5 = { @@ -134,6 +134,11 @@ def test_tender_wizard_form_all_good_authenticated(self): self.assertEqual(tender.contact_last_name, self.user_buyer.last_name) self.assertEqual(tender.contact_email, self.user_buyer.email) self.assertEqual(tender.contact_phone_display, self.user_buyer.phone_display) + self.assertEqual(tender.scale_marche_useless, tenders_step_data[3].get("survey-scale_marche_useless")) + self.assertEqual( + tender.le_marche_doesnt_exist_how_to_find_siae, + tenders_step_data[3].get("survey-le_marche_doesnt_exist_how_to_find_siae"), + ) def test_tender_wizard_form_not_created(self): self.client.force_login(self.user_buyer) @@ -1516,7 +1521,7 @@ def test_user_can_notify_cocontracting_wish_with_authenticated_user(self): self.assertContains(response, self.cta_message_success) 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.assertTrue(f"La structure {self.siae.name} souhaite répondre en co-traitance" in email_body) self.assertIsNotNone(tendersiae.detail_cocontracting_click_date) response = self.client.get(self.tender_detail_url) self.assertNotContains(response, self.cta_message) diff --git a/lemarche/www/tenders/views.py b/lemarche/www/tenders/views.py index 9557418ce..fa0d5acc0 100644 --- a/lemarche/www/tenders/views.py +++ b/lemarche/www/tenders/views.py @@ -196,25 +196,21 @@ def save_instance_tender(self, tender_dict: dict, form_dict: dict, is_draft: boo sectors = None for step, model_form in form_dict.items(): if model_form.has_changed(): - if step != self.STEP_SURVEY: - for attribute in model_form.changed_data: - match attribute: - case "sectors": - sectors = tender_dict.get("sectors", None) - self.instance.sectors.set(sectors) - case "location": - location = tender_dict.get("location") - self.instance.location = location - self.instance.perimeters.set([location]) - case "questions_list": - update_or_create_questions_list( - tender=self.instance, questions_list=tender_dict.get("questions_list") - ) - case _: - setattr(self.instance, attribute, tender_dict.get(attribute)) - elif step == self.STEP_SURVEY: - setattr(self.instance, "scale_marche_useless", tender_dict.get("scale_marche_useless")) - self.instance.extra_data.update(tender_dict.get("extra_data")) + for attribute in model_form.changed_data: + match attribute: + case "sectors": + sectors = tender_dict.get("sectors", None) + self.instance.sectors.set(sectors) + case "location": + location = tender_dict.get("location") + self.instance.location = location + self.instance.perimeters.set([location]) + case "questions_list": + update_or_create_questions_list( + tender=self.instance, questions_list=tender_dict.get("questions_list") + ) + case _: + setattr(self.instance, attribute, tender_dict.get(attribute)) self.instance.save() else: tender_dict |= {"status": tender_status, "published_at": tender_published_at}