From 7066e77422fd6037b8e2c8bacac557715f8e26a2 Mon Sep 17 00:00:00 2001 From: Amandine Date: Tue, 29 Oct 2024 17:07:29 +0100 Subject: [PATCH] Filtrer sites/visites dans contexte d'un module (#377) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Filtrer visites dans contexte d'un module * Cas hors contexte module * Sites des groupes de sites dans le contexte d'un module * Filtre site sur visite * Date dernière visite --- .../gn_module_monitoring/monitoring/models.py | 109 +++++++++++++++--- .../monitoring/schemas.py | 3 + .../monitoring-object.component.ts | 2 +- frontend/app/services/geojson.service.ts | 2 +- 4 files changed, 96 insertions(+), 20 deletions(-) diff --git a/backend/gn_module_monitoring/monitoring/models.py b/backend/gn_module_monitoring/monitoring/models.py index 63693fb0b..5639707f0 100644 --- a/backend/gn_module_monitoring/monitoring/models.py +++ b/backend/gn_module_monitoring/monitoring/models.py @@ -9,10 +9,8 @@ from uuid import uuid4 from sqlalchemy import join, select, func, and_ -from sqlalchemy.orm import ( - column_property, - aliased, -) +from sqlalchemy.orm import column_property, aliased + from sqlalchemy.dialects.postgresql import JSONB, UUID from utils_flask_sqla.serializers import serializable @@ -229,6 +227,18 @@ def organism_actors(self): return actors_organism_list def has_instance_permission(self, scope): + # Filtre sur le contexte du module + # Si dans un sous module, on ne peut voir que les + # visites de ce module + + if getattr(g, "current_module", None): + if ( + not g.current_module.module_code == "MONITORINGS" + and not self.id_module == g.current_module.id_module + ): + return False + + # Filtre sur les permissions if scope == 0: return False elif scope in (1, 2): @@ -288,15 +298,53 @@ class TMonitoringSites(TBaseSites, PermissionModel, SitesQuery): .scalar_subquery() ) - nb_visits = column_property( - select(func.count(TBaseVisits.id_base_site)) - .where(TBaseVisits.id_base_site == id_base_site) - .scalar_subquery() - ) - geom_geojson = column_property(func.ST_AsGeoJSON(TBaseSites.geom), deferred=True) types_site = DB.relationship("BibTypeSite", secondary=cor_site_type, overlaps="sites") + @hybrid_property + def last_visit(self): + query = select(func.max(TBaseVisits.visit_date_min)).where( + TBaseVisits.id_base_site == self.id_base_site + ) + # Filtre sur le contexte du module + # Si dans un sous module, on ne dénombre les visites de ce module + if getattr(g, "current_module", None): + if not g.current_module.module_code == "MONITORINGS": + query = query.where(TMonitoringVisits.id_module == g.current_module.id_module) + return DB.session.scalar(query) + + @last_visit.expression + def last_visit(cls): + query = select(func.max(TBaseVisits.visit_date_min)).where( + TBaseVisits.id_base_site == cls.id_base_site + ) + if getattr(g, "current_module", None): + if not g.current_module.module_code == "MONITORINGS": + query = query.where(TMonitoringVisits.id_module == g.current_module.id_module) + return query.as_scalar() + + @hybrid_property + def nb_visits(self): + query = select(func.count(TBaseVisits.id_base_site)).where( + TBaseVisits.id_base_site == self.id_base_site + ) + # Filtre sur le contexte du module + # Si dans un sous module, on ne dénombre les visites de ce module + if getattr(g, "current_module", None): + if not g.current_module.module_code == "MONITORINGS": + query = query.where(TMonitoringVisits.id_module == g.current_module.id_module) + return DB.session.scalar(query) + + @nb_visits.expression + def nb_visits(cls): + query = select(func.count(TBaseVisits.id_base_site)).where( + TBaseVisits.id_base_site == cls.id_base_site + ) + if getattr(g, "current_module", None): + if not g.current_module.module_code == "MONITORINGS": + query = query.where(TMonitoringVisits.id_module == g.current_module.id_module) + return query.as_scalar() + @hybrid_property def organism_actors(self): actors_organism_list = [] @@ -310,6 +358,15 @@ def organism_actors(self): return actors_organism_list def has_instance_permission(self, scope): + # Filtre sur le contexte du module + # Si dans un sous module, on ne peut voir que les + # site du type de ce module + if getattr(g, "current_module", None): + if not g.current_module.module_code == "MONITORINGS" and ( + not (set(g.current_module.types_site) & set(self.types_site)) + ): + return False + if scope == 0: return False elif scope in (1, 2): @@ -375,14 +432,6 @@ class TMonitoringSitesGroups(DB.Model, PermissionModel, SitesGroupsQuery): altitude_min = DB.Column(DB.Integer) altitude_max = DB.Column(DB.Integer) - nb_visits = column_property( - select(func.count(TMonitoringVisits.id_base_site)) - .where( - TMonitoringVisits.id_base_site == TMonitoringSites.id_base_site, - TMonitoringSites.id_sites_group == id_sites_group, - ) - .scalar_subquery() - ) geom_geojson = column_property( select(func.st_asgeojson(func.st_convexHull(func.st_collect(TMonitoringSites.geom)))) @@ -392,6 +441,30 @@ class TMonitoringSitesGroups(DB.Model, PermissionModel, SitesGroupsQuery): .scalar_subquery() ) + @hybrid_property + def nb_visits(self): + query = select(func.count(TMonitoringVisits.id_base_site)).where( + TMonitoringVisits.id_base_site == TMonitoringSites.id_base_site, + TMonitoringSites.id_sites_group == self.id_sites_group, + ) + # Filtre sur le contexte du module + # Si dans un sous module, on ne dénombre que les visites de ce module + if getattr(g, "current_module", None): + if not g.current_module.module_code == "MONITORINGS": + query = query.where(TMonitoringVisits.id_module == g.current_module.id_module) + return DB.session.scalar(query) + + @nb_visits.expression + def nb_visits(cls): + query = select(func.count(TMonitoringVisits.id_base_site)).where( + TMonitoringVisits.id_base_site == TMonitoringSites.id_base_site, + TMonitoringSites.id_sites_group == cls.id_sites_group, + ) + if getattr(g, "current_module", None): + if not g.current_module.module_code == "MONITORINGS": + query = query.where(TMonitoringVisits.id_module == g.current_module.id_module) + return query.as_scalar() + @hybrid_property def organism_actors(self): # return self.digitiser.id_organisme diff --git a/backend/gn_module_monitoring/monitoring/schemas.py b/backend/gn_module_monitoring/monitoring/schemas.py index fd4434410..b33e37c89 100644 --- a/backend/gn_module_monitoring/monitoring/schemas.py +++ b/backend/gn_module_monitoring/monitoring/schemas.py @@ -88,6 +88,7 @@ class Meta: id_digitiser = fields.Method("get_id_digitiser") is_geom_from_child = fields.Method("set_is_geom_from_child", dump_only=True) modules = MA.Pluck(ModuleSchema, "id_module", many=True) + nb_visits = fields.Integer(dump_only=True) def get_id_digitiser(self, obj): return obj.id_digitiser @@ -142,6 +143,8 @@ class Meta: id_inventor = fields.Method("get_id_inventor") inventor = fields.Method("get_inventor_name") medias = MA.Nested(MediaSchema, many=True) + nb_visits = fields.Integer(dump_only=True) + last_visit = fields.DateTime(dump_only=True) def serialize_geojson(self, obj): if obj.geom is not None: diff --git a/frontend/app/components/monitoring-object/monitoring-object.component.ts b/frontend/app/components/monitoring-object/monitoring-object.component.ts index cf7c66b6b..ced4b177a 100644 --- a/frontend/app/components/monitoring-object/monitoring-object.component.ts +++ b/frontend/app/components/monitoring-object/monitoring-object.component.ts @@ -177,7 +177,7 @@ export class MonitoringObjectComponent implements OnInit { pre_filters['site']['id_base_site'] = this.obj.id; } else if (this.obj['siteId'] !== undefined) { // affichage du site parent - pre_filters['id_base_site'] = this.obj['siteId']; + pre_filters['site']['id_base_site'] = this.obj['siteId']; } else if (queryParams['id_base_site'] !== undefined) { // récupération du site parent via l'url pre_filters['site']['id_base_site'] = queryParams['id_base_site']; diff --git a/frontend/app/services/geojson.service.ts b/frontend/app/services/geojson.service.ts index d01a2ac9b..fb2bdf8e8 100644 --- a/frontend/app/services/geojson.service.ts +++ b/frontend/app/services/geojson.service.ts @@ -61,8 +61,8 @@ export class GeoJSONService { getSitesGroupsGeometriesWithSites( sitesGroupOnEachFeature: Function, sitesOnEachFeature: Function, - paramsSite = {}, paramsSitesGroup = {}, + paramsSite = {}, sitesGroupstyle?, sitesStyle? ) {