diff --git a/core/fields.py b/core/fields.py
index fd0b2ca..097e2f6 100644
--- a/core/fields.py
+++ b/core/fields.py
@@ -1,24 +1,27 @@
from django import forms
from django.contrib.contenttypes.models import ContentType
+from django.core.exceptions import ObjectDoesNotExist
+from core.content_types import content_type_str_to_obj
-class MultiModelChoiceField(forms.ChoiceField):
+
+class MultiModelChoiceField(forms.MultipleChoiceField):
def __init__(self, model_choices, *args, **kwargs):
choices = []
for label, queryset in model_choices:
content_type = ContentType.objects.get_for_model(queryset.model)
- model_choices = [(f"{content_type.id}-{obj.id}", f"{label}: {obj}") for obj in queryset]
+ model_choices = [(f"{content_type.id}-{obj.id}", f"{label} : {obj}") for obj in queryset]
choices.extend(model_choices)
super().__init__(choices=choices, *args, **kwargs)
def clean(self, value):
- content_type_id, object_id = value.split("-")
- content_type = ContentType.objects.get(id=content_type_id)
- model_class = content_type.model_class()
- try:
- return model_class.objects.get(id=object_id)
- except model_class.DoesNotExist:
- raise forms.ValidationError("L'objet sélectionné n'existe pas.")
+ list_of_objects = []
+ for obj_as_str in value:
+ try:
+ list_of_objects.append(content_type_str_to_obj(obj_as_str))
+ except ObjectDoesNotExist:
+ raise forms.ValidationError("L'un des objets sélectionnés n'existe pas.")
+ return list_of_objects
class DSFRCheckboxSelectMultiple(forms.CheckboxSelectMultiple):
diff --git a/core/mixins.py b/core/mixins.py
index 704e27b..a9afa9c 100644
--- a/core/mixins.py
+++ b/core/mixins.py
@@ -194,3 +194,17 @@ def can_user_access(self, user):
return True
case _:
return False
+
+
+class WithFreeLinkIdsMixin:
+ @property
+ def free_link_ids(self):
+ content_type = ContentType.objects.get_for_model(self)
+ links = LienLibre.objects.for_object(self).select_related("content_type_2", "content_type_1")
+ link_ids = []
+ for link in links:
+ if link.object_id_1 == self.id and link.content_type_1 == content_type:
+ link_ids.append(f"{link.content_type_2.pk}-{link.object_id_2}")
+ else:
+ link_ids.append(f"{link.content_type_1.pk}-{link.object_id_1}")
+ return link_ids
diff --git a/sv/forms.py b/sv/forms.py
index 836879b..91f2a82 100644
--- a/sv/forms.py
+++ b/sv/forms.py
@@ -1,6 +1,5 @@
-from core.forms import DSFRForm, WithNextUrlMixin, VisibiliteUpdateBaseForm
+from core.forms import DSFRForm, VisibiliteUpdateBaseForm
-from django.contrib.contenttypes.models import ContentType
from core.fields import MultiModelChoiceField
from django import forms
from django.forms.models import inlineformset_factory
@@ -15,37 +14,6 @@
from sv.models import FicheZoneDelimitee, ZoneInfestee, OrganismeNuisible, StatutReglementaire, FicheDetection
-class FreeLinkForm(DSFRForm, WithNextUrlMixin, forms.ModelForm):
- object_id_1 = forms.IntegerField(widget=forms.HiddenInput())
- content_type_1 = forms.ModelChoiceField(widget=forms.HiddenInput(), queryset=ContentType.objects.all())
-
- class Meta:
- fields = ["object_id_1", "content_type_1"]
- model = LienLibre
-
- def __init__(self, *args, **kwargs):
- object_id_1 = kwargs.pop("object_id_1", None)
- content_type_1 = kwargs.pop("content_type_1", None)
- next = kwargs.pop("next", None)
- super().__init__(*args, **kwargs)
- self.fields["object_choice"] = MultiModelChoiceField(
- label="Sélectioner un objet",
- model_choices=[
- ("Fiche Detection", FicheDetection.objects.select_related("numero")),
- ("Fiche Zone Delimitee", FicheZoneDelimitee.objects.select_related("numero")),
- ],
- )
- self.add_next_field(next)
- self.fields["object_id_1"].initial = object_id_1
- self.fields["content_type_1"].initial = content_type_1
-
- def clean(self):
- super().clean()
- obj = self.cleaned_data["object_choice"]
- self.instance.content_type_2 = ContentType.objects.get_for_model(obj)
- self.instance.object_id_2 = obj.id
-
-
class FicheDetectionVisibiliteUpdateForm(VisibiliteUpdateBaseForm, forms.ModelForm):
class Meta:
model = FicheDetection
@@ -129,6 +97,17 @@ def __init__(self, *args, **kwargs):
if self.instance.pk:
self.fields.pop("visibilite")
+ qs_detection = FicheDetection.objects.all().get_fiches_user_can_view(self.user).select_related("numero")
+ qs_zone = FicheZoneDelimitee.objects.all().get_fiches_user_can_view(self.user).select_related("numero")
+ self.fields["free_link"] = MultiModelChoiceField(
+ required=False,
+ label="Sélectionner un objet",
+ model_choices=[
+ ("Fiche Détection", qs_detection),
+ ("Fiche zone délimitée", qs_zone),
+ ],
+ )
+
organisme_nuisible_libelle = self.data.get("organisme_nuisible") or self.initial.get("organisme_nuisible")
self.fields["detections_hors_zone"].queryset = (
FicheDetection.objects.all()
@@ -167,8 +146,23 @@ def save(self, commit=True):
if commit:
instance.save()
self.save_detections_hors_zone(instance)
+ self.save_free_links(instance)
return instance
+ def save_free_links(self, instance):
+ links_ids_to_keep = []
+ for obj in self.cleaned_data["free_link"]:
+ link = LienLibre.objects.for_both_objects(obj, instance)
+
+ if link:
+ links_ids_to_keep.append(link.id)
+ else:
+ link = LienLibre.objects.create(related_object_1=instance, related_object_2=obj)
+ links_ids_to_keep.append(link.id)
+
+ links_to_delete = LienLibre.objects.for_object(instance).exclude(id__in=links_ids_to_keep)
+ links_to_delete.delete()
+
def save_detections_hors_zone(self, instance):
detections_from_form = set(self.cleaned_data.get("detections_hors_zone", []))
detections_from_db = set(FicheDetection.objects.filter(hors_zone_infestee=instance))
diff --git a/sv/managers.py b/sv/managers.py
index 374c717..f704d46 100644
--- a/sv/managers.py
+++ b/sv/managers.py
@@ -101,3 +101,17 @@ def get_contacts_structures_not_in_fin_suivi(self, fiche_zone_delimitee):
fin_suivi_contacts_ids = fiche_zone_delimitee.fin_suivi.values_list("contact", flat=True)
contacts_not_in_fin_suivi = contacts_structure_fiche.exclude(id__in=fin_suivi_contacts_ids)
return contacts_not_in_fin_suivi
+
+ def get_fiches_user_can_view(self, user):
+ if user.agent.structure.is_mus_or_bsv:
+ return self.filter(
+ Q(visibilite__in=[Visibilite.LOCAL, Visibilite.NATIONAL])
+ | Q(visibilite=Visibilite.BROUILLON, createur=user.agent.structure)
+ )
+ return self.filter(
+ Q(visibilite=Visibilite.NATIONAL)
+ | Q(
+ visibilite__in=[Visibilite.BROUILLON, Visibilite.LOCAL],
+ createur=user.agent.structure,
+ )
+ )
diff --git a/sv/models.py b/sv/models.py
index eba12af..7dcbf44 100644
--- a/sv/models.py
+++ b/sv/models.py
@@ -1,4 +1,3 @@
-from django.contrib.contenttypes.models import ContentType
from django.db import models, transaction
from django.core.validators import RegexValidator
from django.db.models import TextChoices, Q
@@ -13,8 +12,9 @@
AllowVisibiliteMixin,
IsActiveMixin,
WithMessageUrlsMixin,
+ WithFreeLinkIdsMixin,
)
-from core.models import Document, Message, Contact, Structure, FinSuiviContact, UnitesMesure, Visibilite, LienLibre
+from core.models import Document, Message, Contact, Structure, FinSuiviContact, UnitesMesure, Visibilite
from sv.managers import (
LaboratoireAgreeManager,
LaboratoireConfirmationOfficielleManager,
@@ -417,6 +417,7 @@ class FicheDetection(
AllowVisibiliteMixin,
WithEtatMixin,
WithMessageUrlsMixin,
+ WithFreeLinkIdsMixin,
models.Model,
):
class Meta:
@@ -521,18 +522,6 @@ def get_fiche_zone_delimitee(self) -> "FicheZoneDelimitee":
if self.zone_infestee and self.zone_infestee.fiche_zone_delimitee:
return self.zone_infestee.fiche_zone_delimitee
- @property
- def free_link_ids(self):
- content_type = ContentType.objects.get_for_model(self)
- links = LienLibre.objects.for_object(self).select_related("content_type_2", "content_type_1")
- link_ids = []
- for link in links:
- if link.object_id_1 == self.id and link.content_type_1 == content_type:
- link_ids.append(f"{link.content_type_2.pk}-{link.object_id_2}")
- else:
- link_ids.append(f"{link.content_type_1.pk}-{link.object_id_1}")
- return link_ids
-
class ZoneInfestee(models.Model):
class UnitesSurfaceInfesteeTotale(TextChoices):
@@ -566,7 +555,7 @@ class Meta:
)
-class FicheZoneDelimitee(AllowVisibiliteMixin, WithEtatMixin, WithMessageUrlsMixin, models.Model):
+class FicheZoneDelimitee(AllowVisibiliteMixin, WithEtatMixin, WithMessageUrlsMixin, WithFreeLinkIdsMixin, models.Model):
class CaracteristiquesPrincipales(models.TextChoices):
PLEIN_AIR_ZONE_PRODUCTION_CHAMP = (
"plein_air_zone_production_champ",
diff --git a/sv/static/sv/fichezone_detail.js b/sv/static/sv/fichezone_detail.js
deleted file mode 100644
index 01f055f..0000000
--- a/sv/static/sv/fichezone_detail.js
+++ /dev/null
@@ -1,8 +0,0 @@
-document.addEventListener('DOMContentLoaded', function() {
- new Choices(document.getElementById('id_object_choice'), {
- classNames: {
- containerInner: 'fr-select',
- },
- itemSelectText: ''
- });
-});
diff --git a/sv/static/sv/fichezone_form.js b/sv/static/sv/fichezone_form.js
index 93a127d..a8953f6 100644
--- a/sv/static/sv/fichezone_form.js
+++ b/sv/static/sv/fichezone_form.js
@@ -20,6 +20,26 @@ function initializeAllChoices() {
}
}
+function inititializeFreeLinksChoices(){
+ const freeLinksChoices = new Choices(document.getElementById("id_free_link"), {
+ searchResultLimit: 500,
+ classNames: {
+ containerInner: 'fr-select',
+ },
+ removeItemButton: true,
+ itemSelectText: '',
+ noResultsText: 'Aucun résultat trouvé',
+ noChoicesText: 'Aucune fiche à sélectionner',
+ searchFields: ['label'],
+ });
+ const freeLinksIds = JSON.parse(document.getElementById('free-links-id').textContent);
+ if (!!freeLinksIds) {
+ freeLinksIds.forEach(value => {
+ freeLinksChoices.setChoiceByValue(value);
+ });
+ }
+}
+
function addZoneInfesteeForm() {
const totalFormsInput = document.getElementById('id_zoneinfestee_set-TOTAL_FORMS');
let totalForms = parseInt(totalFormsInput.value);
@@ -37,6 +57,7 @@ document.addEventListener('DOMContentLoaded', function() {
initializeChoices('id_detections_hors_zone');
initializeAllChoices();
+ inititializeFreeLinksChoices();
const addZoneButton = document.getElementById('add-zone-infestee');
addZoneButton.addEventListener('click', function(event) {
event.preventDefault();
diff --git a/sv/templates/sv/fichezonedelimitee_detail.html b/sv/templates/sv/fichezonedelimitee_detail.html
index a7cd8ae..419b8cf 100644
--- a/sv/templates/sv/fichezonedelimitee_detail.html
+++ b/sv/templates/sv/fichezonedelimitee_detail.html
@@ -9,9 +9,6 @@
{% endblock %}
-{% block scripts %}
-
-{% endblock %}
{% block content %}
diff --git a/sv/templates/sv/fichezonedelimitee_form.html b/sv/templates/sv/fichezonedelimitee_form.html
index 1d70ee6..0bb1e68 100644
--- a/sv/templates/sv/fichezonedelimitee_form.html
+++ b/sv/templates/sv/fichezonedelimitee_form.html
@@ -240,7 +240,17 @@
Zones infestées
+
+
+
+ {{ form.instance.free_link_ids|json_script:"free-links-id" }}
+
Liens libres
+
+ {{ form.free_link }}
+
+
+
{% endblock %}
diff --git a/sv/tests/test_fichedetection_create.py b/sv/tests/test_fichedetection_create.py
index 83f90a0..c5835b7 100644
--- a/sv/tests/test_fichedetection_create.py
+++ b/sv/tests/test_fichedetection_create.py
@@ -22,7 +22,7 @@
)
from sv.constants import REGIONS, DEPARTEMENTS
-from core.models import Contact, LienLibre, Visibilite
+from core.models import Contact, LienLibre, Visibilite, Structure
from sv.constants import STATUTS_EVENEMENT, STATUTS_REGLEMENTAIRES, CONTEXTES
@@ -427,3 +427,25 @@ def test_fiche_detection_with_free_link(
assert lien_libre.related_object_1 == fiche_detection
assert lien_libre.related_object_2 == fiche_zone
+
+
+@pytest.mark.django_db
+def test_fiche_detection_with_free_link_cant_see_draft(
+ live_server,
+ page: Page,
+ form_elements: FicheDetectionFormDomElements,
+ mocked_authentification_user,
+ fiche_zone_bakery,
+ choice_js_fill,
+):
+ fiche_zone = fiche_zone_bakery()
+ fiche_zone.visibilite = Visibilite.BROUILLON
+ fiche_zone.createur = baker.make(Structure)
+ fiche_zone.save()
+
+ page.goto(f"{live_server.url}{reverse('fiche-detection-creation')}")
+ fiche_input = "Fiche zone délimitée : " + str(fiche_zone.numero)
+ page.query_selector("#liens-libre .choices").click()
+ page.wait_for_selector("input:focus", state="visible", timeout=2_000)
+ page.locator("*:focus").fill(str(fiche_zone.numero))
+ expect(page.get_by_role("option", name=fiche_input, exact=True)).not_to_be_visible()
diff --git a/sv/tests/test_fichedetection_performances.py b/sv/tests/test_fichedetection_performances.py
index 8783ee4..3ad9ae7 100644
--- a/sv/tests/test_fichedetection_performances.py
+++ b/sv/tests/test_fichedetection_performances.py
@@ -4,7 +4,7 @@
from core.models import Message, Document, Structure, Contact
from sv.models import FicheDetection, Lieu, Prelevement
-BASE_NUM_QUERIES = 15 # Please note a first call is made without assertion to warm up any possible cache
+BASE_NUM_QUERIES = 13 # Please note a first call is made without assertion to warm up any possible cache
@pytest.mark.django_db
diff --git a/sv/tests/test_fichezonedelimitee_add_performance.py b/sv/tests/test_fichezonedelimitee_add_performance.py
index abde845..8718031 100644
--- a/sv/tests/test_fichezonedelimitee_add_performance.py
+++ b/sv/tests/test_fichezonedelimitee_add_performance.py
@@ -6,7 +6,7 @@
from sv.forms import RattachementChoices
from sv.models import Etat, OrganismeNuisible, FicheDetection
-BASE_NUM_QUERIES = 9
+BASE_NUM_QUERIES = 12
def test_add_fiche_zone_delimitee_form_with_multiple_existing_fiche_detection(
diff --git a/sv/tests/test_fichezonedelimitee_create.py b/sv/tests/test_fichezonedelimitee_create.py
index ea11cb8..d880c38 100644
--- a/sv/tests/test_fichezonedelimitee_create.py
+++ b/sv/tests/test_fichezonedelimitee_create.py
@@ -4,7 +4,7 @@
from django.utils import timezone
from django.urls import reverse
-from core.models import Visibilite
+from core.models import Visibilite, LienLibre
from sv.models import FicheZoneDelimitee, ZoneInfestee, FicheDetection, Etat
from sv.tests.test_utils import FicheZoneDelimiteeFormPage
from sv.forms import RattachementChoices
@@ -324,3 +324,31 @@ def test_cant_link_fiche_detection_to_fiche_zone_delimitee_if_fiche_detection_is
expect(page.get_by_text("Aucune fiche détection à sélectionner").nth(1)).to_be_visible()
page.get_by_text("Rattacher des détections").nth(2).click()
expect(page.get_by_text("Aucune fiche détection à sélectionner").nth(2)).to_be_visible()
+
+
+@pytest.mark.django_db
+def test_can_create_fiche_zone_with_free_links(
+ live_server, page: Page, choice_js_fill, fiche_detection: FicheDetection, fiche_zone_bakery
+):
+ other_fiche = fiche_zone_bakery()
+ other_fiche.visibilite = Visibilite.NATIONAL
+ other_fiche.save()
+ fiche_detection.organisme_nuisible = baker.make("OrganismeNuisible")
+ fiche_detection.statut_reglementaire = baker.make("StatutReglementaire")
+ fiche_detection.save()
+ form_page = FicheZoneDelimiteeFormPage(page, choice_js_fill)
+
+ form_page.goto_create_form_page(live_server, fiche_detection.pk, RattachementChoices.HORS_ZONE_INFESTEE)
+ fiche_input = "Fiche zone délimitée : " + str(other_fiche.numero)
+ choice_js_fill(page, "#liens-libre .choices", str(other_fiche.numero), fiche_input)
+ form_page.submit_form()
+
+ form_page.check_message_succes()
+ assert FicheZoneDelimitee.objects.count() == 2
+ fiche_from_db = FicheZoneDelimitee.objects.last()
+
+ assert LienLibre.objects.count() == 1
+ lien_libre = LienLibre.objects.get()
+
+ assert lien_libre.related_object_1 == fiche_from_db
+ assert lien_libre.related_object_2 == other_fiche
diff --git a/sv/tests/test_fichezonedelimitee_detail_performances.py b/sv/tests/test_fichezonedelimitee_detail_performances.py
index f4f16e1..bec3d27 100644
--- a/sv/tests/test_fichezonedelimitee_detail_performances.py
+++ b/sv/tests/test_fichezonedelimitee_detail_performances.py
@@ -1,7 +1,7 @@
from model_bakery import baker
from sv.models import FicheDetection, ZoneInfestee
-BASE_NUM_QUERIES = 16
+BASE_NUM_QUERIES = 14
def test_empty_fiche_zone_delimitee_performances(
diff --git a/sv/tests/test_fichezonedelimitee_update.py b/sv/tests/test_fichezonedelimitee_update.py
index 2e2c104..18919a4 100644
--- a/sv/tests/test_fichezonedelimitee_update.py
+++ b/sv/tests/test_fichezonedelimitee_update.py
@@ -1,5 +1,7 @@
from playwright.sync_api import Page, expect
from model_bakery import baker
+
+from core.models import LienLibre
from sv.tests.test_utils import FicheZoneDelimiteeFormPage
from sv.models import ZoneInfestee, FicheZoneDelimitee, FicheDetection, Etat
@@ -174,3 +176,42 @@ def test_update_form_cant_have_same_detection_in_two_zone_infestee(
f"Les fiches détection suivantes sont dupliquées dans les zones infestées : {str(fiche_detection.numero)}."
)
).to_be_visible()
+
+
+def test_update_fiche_can_add_and_delete_free_links(
+ live_server,
+ page: Page,
+ fiche_detection: FicheDetection,
+ fiche_detection_bakery,
+ choice_js_fill,
+):
+ other_fiche = fiche_detection_bakery()
+ other_fiche_2 = fiche_detection_bakery()
+ fiche_zone_delimitee = baker.make(
+ FicheZoneDelimitee,
+ etat=Etat.objects.get(id=Etat.get_etat_initial()),
+ organisme_nuisible=fiche_detection.organisme_nuisible,
+ statut_reglementaire=fiche_detection.statut_reglementaire,
+ _fill_optional=True,
+ )
+ LienLibre.objects.create(related_object_1=fiche_zone_delimitee, related_object_2=other_fiche)
+ form_page = FicheZoneDelimiteeFormPage(page, choice_js_fill)
+ page.goto(f"{live_server.url}{fiche_zone_delimitee.get_update_url()}")
+
+ expect(page.get_by_text(f"Fiche Détection : {str(other_fiche.numero)}Remove item")).to_be_visible()
+ # Remove existing link
+ page.locator(".choices__button").click()
+
+ # Add new link
+ fiche_input = "Fiche Détection : " + str(other_fiche_2.numero)
+ choice_js_fill(page, "#liens-libre .choices", str(other_fiche_2.numero), fiche_input)
+
+ form_page.submit_update_form()
+
+ page.wait_for_timeout(600)
+
+ assert LienLibre.objects.count() == 1
+ lien_libre = LienLibre.objects.get()
+
+ assert lien_libre.related_object_1 == fiche_zone_delimitee
+ assert lien_libre.related_object_2 == other_fiche_2
diff --git a/sv/tests/test_fichezonedelimitee_update_performance.py b/sv/tests/test_fichezonedelimitee_update_performance.py
index 8ed871c..77f274a 100644
--- a/sv/tests/test_fichezonedelimitee_update_performance.py
+++ b/sv/tests/test_fichezonedelimitee_update_performance.py
@@ -3,7 +3,7 @@
from core.models import Visibilite
from sv.models import Etat, OrganismeNuisible, FicheDetection
-BASE_NUM_QUERIES = 10
+BASE_NUM_QUERIES = 13
def test_update_fiche_zone_delimitee_form_with_multiple_existing_fiche_detection(
diff --git a/sv/urls.py b/sv/urls.py
index 2313a58..8660c25 100644
--- a/sv/urls.py
+++ b/sv/urls.py
@@ -6,7 +6,6 @@
FicheDetectionDetailView,
FicheDetectionCreateView,
FicheDetectionUpdateView,
- FreeLinkCreateView,
FicheDetectionExportView,
FicheCloturerView,
FicheDetectionVisibiliteUpdateView,
@@ -63,11 +62,6 @@
RattachementDetectionView.as_view(),
name="rattachement-fiche-zone-delimitee",
),
- path(
- "lien/ajout/",
- FreeLinkCreateView.as_view(),
- name="free-link-add",
- ),
path(
"api/espece/recherche/",
search_espece_echantillon,
diff --git a/sv/views.py b/sv/views.py
index 1254e22..e54d8a0 100644
--- a/sv/views.py
+++ b/sv/views.py
@@ -15,7 +15,7 @@
)
from django.urls import reverse
from django.db.models import F, Prefetch
-from django.db import transaction, IntegrityError
+from django.db import transaction
from django.http import HttpResponseBadRequest, HttpResponseRedirect, HttpResponse
from django.core.exceptions import ValidationError, PermissionDenied, ObjectDoesNotExist
from django.contrib import messages
@@ -31,7 +31,6 @@
)
from core.redirect import safe_redirect
from sv.forms import (
- FreeLinkForm,
FicheDetectionVisibiliteUpdateForm,
FicheZoneDelimiteeForm,
ZoneInfesteeFormSet,
@@ -114,11 +113,6 @@ def get_object(self, queryset=None):
self.object = super().get_object(queryset)
return self.object
- def _get_free_link_form(self):
- return FreeLinkForm(
- content_type_1=ContentType.objects.get_for_model(self.get_object()).pk, object_id_1=self.get_object().pk
- )
-
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["lieux"] = (
@@ -133,7 +127,6 @@ def get_context_data(self, **kwargs):
"espece_echantillon",
"laboratoire_agree",
)
- context["free_link_form"] = self._get_free_link_form()
context["content_type"] = ContentType.objects.get_for_model(self.get_object())
contacts_not_in_fin_suivi = FicheDetection.objects.all().get_contacts_structures_not_in_fin_suivi(
self.get_object()
@@ -156,6 +149,29 @@ def handle_no_permission(self):
class FicheDetectionContextMixin:
+ def _add_status_to_organisme_nuisible(self, context, status):
+ status_code_to_id = {s.code: s.id for s in status}
+ oeep_to_nuisible_id = {
+ organisme.code_oepp: organisme.id
+ for organisme in OrganismeNuisible.objects.filter(code_oepp__in=KNOWN_OEPPS)
+ }
+ context["status_to_organisme_nuisible"] = [
+ {"statusID": status_code_to_id[code], "nuisibleIds": [oeep_to_nuisible_id.get(oepp) for oepp in oepps]}
+ for code, oepps in KNOWN_OEPP_CODES_FOR_STATUS_REGLEMENTAIRES.items()
+ ]
+
+ def _add_possible_links(self, context, user):
+ possible_links = []
+
+ content_type = ContentType.objects.get_for_model(FicheDetection)
+ queryset = FicheDetection.objects.all().get_fiches_user_can_view(user).select_related("numero")
+ possible_links.append((content_type.pk, "Fiche Détection", queryset))
+
+ content_type = ContentType.objects.get_for_model(FicheZoneDelimitee)
+ queryset = FicheZoneDelimitee.objects.all().get_fiches_user_can_view(user).select_related("numero")
+ possible_links.append((content_type.pk, "Fiche zone délimitée", queryset))
+ context["possible_links"] = possible_links
+
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["statuts_evenement"] = StatutEvenement.objects.all()
@@ -183,26 +199,8 @@ def get_context_data(self, **kwargs):
context["types_etablissement"] = TypeExploitant.objects.all().order_by("libelle")
context["positions_chaine_distribution"] = PositionChaineDistribution.objects.all().order_by("libelle")
- status_code_to_id = {s.code: s.id for s in status}
-
- oeep_to_nuisible_id = {
- organisme.code_oepp: organisme.id
- for organisme in OrganismeNuisible.objects.filter(code_oepp__in=KNOWN_OEPPS)
- }
- context["status_to_organisme_nuisible"] = [
- {"statusID": status_code_to_id[code], "nuisibleIds": [oeep_to_nuisible_id.get(oepp) for oepp in oepps]}
- for code, oepps in KNOWN_OEPP_CODES_FOR_STATUS_REGLEMENTAIRES.items()
- ]
-
- possible_links = []
- content_type = ContentType.objects.get_for_model(FicheDetection)
- possible_links.append((content_type.pk, "Fiche Détection", FicheDetection.objects.select_related("numero")))
- content_type = ContentType.objects.get_for_model(FicheZoneDelimitee)
- possible_links.append(
- (content_type.pk, "Fiche zone délimitée", FicheZoneDelimitee.objects.select_related("numero"))
- )
-
- context["possible_links"] = possible_links
+ self._add_status_to_organisme_nuisible(context, status)
+ self._add_possible_links(context, self.request.user)
return context
@@ -644,25 +642,6 @@ def post(self, request, pk):
return redirect(reverse("fiche-detection-vue-detaillee", args=[fiche_detection.pk]))
-class FreeLinkCreateView(FormView):
- form_class = FreeLinkForm
-
- def post(self, request, *args, **kwargs):
- form = FreeLinkForm(request.POST)
- if not form.is_valid():
- messages.error(request, "Ce lien existe déjà.")
- return safe_redirect(self.request.POST.get("next"))
-
- try:
- form.save()
- except IntegrityError:
- messages.error(request, "Vous ne pouvez pas lier un objet à lui même.")
- return safe_redirect(self.request.POST.get("next"))
-
- messages.success(request, "Le lien a été créé avec succès.")
- return safe_redirect(self.request.POST.get("next"))
-
-
class FicheDetectionExportView(View):
http_method_names = ["post"]
@@ -868,11 +847,6 @@ def get_object(self, queryset=None):
self.object = super().get_object(queryset)
return self.object
- def _get_free_link_form(self):
- return FreeLinkForm(
- content_type_1=ContentType.objects.get_for_model(self.get_object()).pk, object_id_1=self.get_object().pk
- )
-
def get_queryset(self):
zone_infestee_detections_prefetch = Prefetch(
"fichedetection_set", queryset=FicheDetection.objects.select_related("numero")
@@ -888,7 +862,6 @@ def get_queryset(self):
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
fichezonedelimitee = self.get_object()
- context["free_link_form"] = self._get_free_link_form()
context["can_update_visibilite"] = self.get_object().can_update_visibilite(self.request.user)
context["visibilite_form"] = FicheDetectionVisibiliteUpdateForm(obj=self.get_object())
context["detections_hors_zone_infestee"] = fichezonedelimitee.fichedetection_set.select_related("numero").all()