From 4b7d680aba2dc09882a0c075b2914fda052f32b7 Mon Sep 17 00:00:00 2001 From: PY Date: Mon, 4 Nov 2024 14:39:12 +0100 Subject: [PATCH] add comments --- envergo/moulinette/models.py | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/envergo/moulinette/models.py b/envergo/moulinette/models.py index dd36b05a5..4765a086c 100644 --- a/envergo/moulinette/models.py +++ b/envergo/moulinette/models.py @@ -1,6 +1,8 @@ import logging from abc import ABC, abstractmethod from collections import OrderedDict +from itertools import groupby +from operator import attrgetter from django.conf import settings from django.contrib.gis.db.models import MultiPolygonField @@ -272,6 +274,19 @@ def result(self): @property def results_by_perimeter(self): + """Compute global result for each perimeter for which this regulation is activated. + + When there is several perimeters, we may want to display some different + information depending on the result of each single perimeter. + E.g. if the project is impacting two different SAGE, we may have some + different required actions for each of them. + + This method is using the same cascading logic as the `result` property, + to reduce multiple criteria results to a single value. + + The results are sorted based on the result cascade, because we want to + display first the most restrictive results. + """ if not self.has_perimeters: return None @@ -279,15 +294,10 @@ def results_by_perimeter(self): # Fetch already evaluated criteria criteria_list = list(self.criteria.all()) - - grouped_criteria = {} - - # Group the criteria by perimeter - for criterion in criteria_list: - perimeter = criterion.perimeter - if perimeter not in grouped_criteria: - grouped_criteria[perimeter] = [] - grouped_criteria[perimeter].append(criterion) + criteria_list.sort(key=attrgetter("perimeter")) + grouped_criteria = { + k: list(v) for k, v in groupby(criteria_list, key=attrgetter("perimeter")) + } for perimeter in self.perimeters.all(): perimeter_criteria = grouped_criteria.get(perimeter, []) @@ -306,7 +316,7 @@ def results_by_perimeter(self): results_by_perimeter[perimeter] = result # sort based on the results cascade - return dict( + return OrderedDict( sorted( results_by_perimeter.items(), key=lambda item: self.result_cascade.index(item[1]),