From 2950487f9cdd0118de375fe625994e5058569100 Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Wed, 1 Feb 2023 07:03:54 +0100 Subject: [PATCH 1/7] #284 Empty API data * adds proper message for certain data parsing in case of an error --- api/utils/serializer/v1/serializer.py | 45 ++++++++++++++++----------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/api/utils/serializer/v1/serializer.py b/api/utils/serializer/v1/serializer.py index 78f8d1f..c01746c 100644 --- a/api/utils/serializer/v1/serializer.py +++ b/api/utils/serializer/v1/serializer.py @@ -297,9 +297,12 @@ class AbstractCompensationAPISerializerV1Mixin: """ deadlines = [] for entry in deadline_data: - deadline_type = entry["type"] - date = entry["date"] - comment = entry["comment"] + try: + deadline_type = entry["type"] + date = entry["date"] + comment = entry["comment"] + except KeyError: + raise ValueError(f"Invalid deadline content. Content was {entry} but should follow the specification") # Check on validity if deadline_type not in DeadlineType: @@ -341,11 +344,14 @@ class AbstractCompensationAPISerializerV1Mixin: """ states = [] for entry in states_data: - biotope_type = entry["biotope"] - biotope_details = [ - self._konova_code_from_json(e, CODELIST_BIOTOPES_EXTRA_CODES_ID) for e in entry["biotope_details"] - ] - surface = float(entry["surface"]) + try: + biotope_type = entry["biotope"] + biotope_details = [ + self._konova_code_from_json(e, CODELIST_BIOTOPES_EXTRA_CODES_ID) for e in entry["biotope_details"] + ] + surface = float(entry["surface"]) + except KeyError: + raise ValueError(f"Invalid biotope content. Content was {entry} but should follow the specification ") # Check on validity if surface <= 0: @@ -385,16 +391,19 @@ class AbstractCompensationAPISerializerV1Mixin: """ actions = [] for entry in actions_data: - action_types = [ - self._konova_code_from_json(e, CODELIST_COMPENSATION_ACTION_ID) for e in entry["action_types"] - ] - action_details = [ - self._konova_code_from_json(e, CODELIST_COMPENSATION_ACTION_DETAIL_ID) for e in entry["action_details"] - ] - amount = float(entry["amount"]) - # Mapping of old "qm" into "m²" - unit = UnitChoices.m2.value if entry["unit"] == "qm" else entry["unit"] - comment = entry["comment"] + try: + action_types = [ + self._konova_code_from_json(e, CODELIST_COMPENSATION_ACTION_ID) for e in entry["action_types"] + ] + action_details = [ + self._konova_code_from_json(e, CODELIST_COMPENSATION_ACTION_DETAIL_ID) for e in entry["action_details"] + ] + amount = float(entry["amount"]) + # Mapping of old "qm" into "m²" + unit = UnitChoices.m2.value if entry["unit"] == "qm" else entry["unit"] + comment = entry["comment"] + except KeyError: + raise ValueError(f"Invalid action content. Content was {entry} but should follow specification") # Check on validity if amount <= 0: From 2e5345e5220c7d1f889fd19e528fdcc6e72b0b81 Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Wed, 1 Feb 2023 08:08:52 +0100 Subject: [PATCH 2/7] #285 Drop atom_id from API * refactors code usage from atom_id to id inside of api app --- api/utils/serializer/v1/serializer.py | 8 ++++---- konova/tests/test_geometries.py | 18 +++++++----------- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/api/utils/serializer/v1/serializer.py b/api/utils/serializer/v1/serializer.py index c01746c..8779f4e 100644 --- a/api/utils/serializer/v1/serializer.py +++ b/api/utils/serializer/v1/serializer.py @@ -61,7 +61,7 @@ class AbstractModelAPISerializerV1(AbstractModelAPISerializer): if konova_code is None: return None return { - "atom_id": konova_code.atom_id, + "id": konova_code.id, "long_name": konova_code.long_name, "short_name": konova_code.short_name, } @@ -70,7 +70,7 @@ class AbstractModelAPISerializerV1(AbstractModelAPISerializer): """ Returns a konova code instance Args: - json_str (str): The value for the code (atom id) + json_str (str): The value for the code (id) code_list_identifier (str): From which konova code list this code is supposed to be from Returns: @@ -83,7 +83,7 @@ class AbstractModelAPISerializerV1(AbstractModelAPISerializer): return None try: code = KonovaCode.objects.get( - atom_id=json_str, + id=json_str, code_lists__in=[code_list_identifier] ) except ObjectDoesNotExist as e: @@ -360,7 +360,7 @@ class AbstractCompensationAPISerializerV1Mixin: # If this exact data is already existing, we do not create it new. Instead put it's id in the list of # entries, we will use to set the new actions state = states_manager.filter( - biotope_type__atom_id=biotope_type, + biotope_type__id=biotope_type, surface=surface, ).exclude( id__in=states diff --git a/konova/tests/test_geometries.py b/konova/tests/test_geometries.py index e73070d..cf51885 100644 --- a/konova/tests/test_geometries.py +++ b/konova/tests/test_geometries.py @@ -9,7 +9,7 @@ from django.contrib.gis.db.models.functions import Translate from konova.models import Geometry, GeometryConflict from konova.tests.test_views import BaseTestCase -from konova.utils.wfs.spatial import ParcelWFSFetcher +from konova.utils.schneider.fetcher import ParcelFetcher class GeometryTestCase(BaseTestCase): @@ -63,18 +63,14 @@ class GeometryTestCase(BaseTestCase): num_conflict = GeometryConflict.objects.all().count() self.assertEqual(0, num_conflict) - def test_wfs_fetch(self): - """ Tests the fetching functionality of ParcelWFSFetcher + def test_fetch(self): + """ Tests the fetching functionality of ParcelFetcher - +++ Test relies on the availability of the RLP Flurstück WFS +++ + +++ Test relies on the availability of the spatial computation component 'Schneider' +++ Returns: """ - fetcher = ParcelWFSFetcher( - geometry_id=self.geom_1.id, - ) - features = fetcher.get_features( - "ave:Flurstueck", - ) - self.assertNotEqual(0, len(features), msg="Spatial wfs get feature did not work!") + fetcher = ParcelFetcher(geometry=self.geom_1) + features = fetcher.get_parcels() + self.assertNotEqual(0, len(features), msg="Spatial fetcher get feature did not work!") From 35c7836b5c66a6fe1f71a319511f973baf8c6b54 Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Wed, 22 Feb 2023 09:19:22 +0100 Subject: [PATCH 3/7] # Improve is_shared_with() * improves central is_shared_with() method of ShareableObjectMixin to run ~30% faster --- konova/models/object.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/konova/models/object.py b/konova/models/object.py index a1c8c9c..90c2f23 100644 --- a/konova/models/object.py +++ b/konova/models/object.py @@ -501,10 +501,13 @@ class ShareableObjectMixin(models.Model): Returns: """ - directly_shared = self.shared_users.filter(id=user.id).exists() - team_shared = self.shared_teams.filter( - users__in=[user] - ).exists() + obj_shared_teams = self.shared_teams + obj_shared_users = self.shared_users + user_shared_teams = user.shared_teams + + directly_shared = obj_shared_users.filter(id=user.id).exists() + team_shared = (obj_shared_teams & user_shared_teams).exists() + is_shared = directly_shared or team_shared return is_shared From acee9daab8a02fb4becb3a3e08202e9a6402b089 Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Wed, 22 Feb 2023 09:44:35 +0100 Subject: [PATCH 4/7] # Improves filter_show_all() * improves performance for filter_show_all() in ShareableTableFilterMixin and CheckboxCompensationTableFilter by ~40% --- compensation/filters/compensation.py | 6 ++++-- konova/filters/mixins/share.py | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/compensation/filters/compensation.py b/compensation/filters/compensation.py index aa1c967..899fd13 100644 --- a/compensation/filters/compensation.py +++ b/compensation/filters/compensation.py @@ -55,10 +55,12 @@ class CheckboxCompensationTableFilter(CheckboxTableFilter): """ if not value: - return queryset.filter( + user_teams = self.user.shared_teams + result = queryset.filter( Q(intervention__users__in=[self.user]) | # requesting user has access - Q(intervention__teams__in=self.user.shared_teams) + Q(intervention__teams__in=user_teams) ).distinct() + return result else: return queryset diff --git a/konova/filters/mixins/share.py b/konova/filters/mixins/share.py index 0c94bdc..598f75f 100644 --- a/konova/filters/mixins/share.py +++ b/konova/filters/mixins/share.py @@ -50,9 +50,11 @@ class ShareableTableFilterMixin(django_filters.FilterSet): """ if not value: - return queryset.filter( + user_teams = self.user.shared_teams + result = queryset.filter( Q(users__in=[self.user]) | # requesting user has access - Q(teams__in=self.user.shared_teams) + Q(teams__in=user_teams) ).distinct() + return result else: return queryset \ No newline at end of file From 073c39a97087361e87300c4f091cac697f711b56 Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Wed, 22 Feb 2023 10:02:56 +0100 Subject: [PATCH 5/7] # Improves home_view() * improves db fetching performance of landing page by ~75% --- konova/views/home.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/konova/views/home.py b/konova/views/home.py index 98cbaee..b62e63e 100644 --- a/konova/views/home.py +++ b/konova/views/home.py @@ -35,6 +35,7 @@ def home_view(request: HttpRequest): template = "konova/home.html" now = timezone.now() user = request.user + user_teams = user.shared_teams # Fetch the four newest active and published ServerMessages msgs = ServerMessage.objects.filter( @@ -51,7 +52,7 @@ def home_view(request: HttpRequest): ) # Then fetch only user related ones user_interventions = interventions.filter( - Q(users__in=[user]) | Q(teams__in=user.shared_teams) + Q(users__in=[user]) | Q(teams__in=user_teams) ).distinct() # Repeat for other objects @@ -59,13 +60,13 @@ def home_view(request: HttpRequest): deleted=None, ) user_comps = comps.filter( - Q(intervention__users__in=[user]) | Q(intervention__teams__in=user.shared_teams) + Q(intervention__users__in=[user]) | Q(intervention__teams__in=user_teams) ).distinct() eco_accs = EcoAccount.objects.filter( deleted=None, ) user_ecco_accs = eco_accs.filter( - Q(users__in=[user]) | Q(teams__in=user.shared_teams) + Q(users__in=[user]) | Q(teams__in=user_teams) ).distinct() additional_context = { From 8e95e980a32969770108c0033e3e224b18314822 Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Wed, 22 Feb 2023 10:53:25 +0100 Subject: [PATCH 6/7] # Reduces db access * reduces number of queries performed on detail views of intervention, compensation and eco_account * renders deductable_rest of eco account beneath progressbar on eco account index view * clarifies ordering logic of related column --- compensation/tables/eco_account.py | 2 ++ compensation/views/compensation/compensation.py | 6 +++++- intervention/views/intervention.py | 7 ++++++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/compensation/tables/eco_account.py b/compensation/tables/eco_account.py index da1444e..64171db 100644 --- a/compensation/tables/eco_account.py +++ b/compensation/tables/eco_account.py @@ -8,6 +8,7 @@ Created on: 18.08.22 from django.http import HttpRequest from django.template.loader import render_to_string from django.urls import reverse +from django.utils.formats import number_format from django.utils.html import format_html from django.utils.translation import gettext_lazy as _ @@ -111,6 +112,7 @@ class EcoAccountTable(BaseTable, TableRenderMixin, TableOrderMixin): except ZeroDivisionError: value_relative = 0 html = render_to_string("konova/widgets/progressbar.html", {"value": value_relative}) + html += f"{number_format(record.deductable_rest, decimal_pos=2)} m²" return format_html(html) def render_r(self, value, record: EcoAccount): diff --git a/compensation/views/compensation/compensation.py b/compensation/views/compensation/compensation.py index d5d7715..e37dc9b 100644 --- a/compensation/views/compensation/compensation.py +++ b/compensation/views/compensation/compensation.py @@ -204,7 +204,11 @@ def detail_view(request: HttpRequest, id: str): """ template = "compensation/detail/compensation/view.html" comp = get_object_or_404( - Compensation, + Compensation.objects.select_related( + "modified", + "created", + "geometry" + ), id=id, deleted=None, intervention__deleted=None, diff --git a/intervention/views/intervention.py b/intervention/views/intervention.py index 0dd59bd..29230f4 100644 --- a/intervention/views/intervention.py +++ b/intervention/views/intervention.py @@ -142,6 +142,8 @@ def detail_view(request: HttpRequest, id: str): "geometry", "legal", "responsible", + ).prefetch_related( + "legal__revocations", ), id=id, deleted=None @@ -158,7 +160,10 @@ def detail_view(request: HttpRequest, id: str): last_checked = intervention.get_last_checked_action() last_checked_tooltip = "" if last_checked: - last_checked_tooltip = DATA_CHECKED_PREVIOUSLY_TEMPLATE.format(last_checked.get_timestamp_str_formatted(), last_checked.user) + last_checked_tooltip = DATA_CHECKED_PREVIOUSLY_TEMPLATE.format( + last_checked.get_timestamp_str_formatted(), + last_checked.user + ) has_payment_without_document = intervention.payments.exists() and not intervention.get_documents()[1].exists() From f3075412eb4336728efd0762ccd96919b7bdd984 Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Thu, 23 Feb 2023 10:17:45 +0100 Subject: [PATCH 7/7] #300 Extend mail templates * extends all relevant mail templates such that municipals of an entry will be shown in the mail --- konova/models/geometry.py | 16 +++ konova/models/object.py | 37 +++-- konova/models/resubmission.py | 4 +- konova/tasks.py | 48 +++---- konova/utils/mailer.py | 66 +++++++-- konova/views/geometry.py | 4 +- locale/de/LC_MESSAGES/django.mo | Bin 46363 -> 46552 bytes locale/de/LC_MESSAGES/django.po | 135 ++++++++++-------- .../email/checking/shared_data_checked.html | 10 ++ .../checking/shared_data_checked_team.html | 10 ++ .../email/deleting/shared_data_deleted.html | 10 ++ .../deleting/shared_data_deleted_team.html | 10 ++ .../email/recording/shared_data_recorded.html | 10 ++ .../recording/shared_data_recorded_team.html | 10 ++ .../recording/shared_data_unrecorded.html | 10 ++ .../shared_data_unrecorded_team.html | 11 ++ .../email/resubmission/resubmission.html | 10 ++ .../email/sharing/shared_access_given.html | 10 ++ .../sharing/shared_access_given_team.html | 11 ++ .../email/sharing/shared_access_removed.html | 10 ++ .../sharing/shared_access_removed_team.html | 10 ++ user/models/team.py | 54 +++---- user/models/user.py | 45 +++--- 23 files changed, 383 insertions(+), 158 deletions(-) diff --git a/konova/models/geometry.py b/konova/models/geometry.py index 79a27e0..f5fa839 100644 --- a/konova/models/geometry.py +++ b/konova/models/geometry.py @@ -276,6 +276,22 @@ class Geometry(BaseResource): return parcels + def get_underlying_municipals(self, parcels=None): + """ Getter for related municipals + + If no QuerySet of parcels is provided, the parcels will be fetched + + Returns: + municipals (QuerySet): The related municipals as queryset + """ + from konova.models import Municipal + + if parcels is None: + parcels = self.get_underlying_parcels() + municipals = parcels.order_by("municipal").distinct("municipal").values("municipal__id") + municipals = Municipal.objects.filter(id__in=municipals).order_by("name") + return municipals + def count_underlying_parcels(self): """ Getter for number of underlying parcels diff --git a/konova/models/object.py b/konova/models/object.py index a1c8c9c..ea62616 100644 --- a/konova/models/object.py +++ b/konova/models/object.py @@ -120,13 +120,14 @@ class DeletableObjectMixin(models.Model): if send_mail: # Send mail shared_users = self.shared_users.values_list("id", flat=True) + municipals_names = list(self.geometry.get_underlying_municipals().values_list("name", flat=True)) for user_id in shared_users: - celery_send_mail_shared_data_deleted.delay(self.identifier, self.title, user_id) + celery_send_mail_shared_data_deleted.delay(self.identifier, self.title, user_id, municipals_names) # Send mail shared_teams = self.shared_teams.values_list("id", flat=True) for team_id in shared_teams: - celery_send_mail_shared_data_deleted_team.delay(self.identifier, self.title, team_id) + celery_send_mail_shared_data_deleted_team.delay(self.identifier, self.title, team_id, municipals_names) self.save() @@ -277,12 +278,13 @@ class RecordableObjectMixin(models.Model): shared_users = self.shared_users.values_list("id", flat=True) shared_teams = self.shared_teams.values_list("id", flat=True) + municipals_names = list(self.geometry.get_underlying_municipals().values_list("name", flat=True)) for user_id in shared_users: - celery_send_mail_shared_data_unrecorded.delay(self.identifier, self.title, user_id) + celery_send_mail_shared_data_unrecorded.delay(self.identifier, self.title, user_id, municipals_names) for team_id in shared_teams: - celery_send_mail_shared_data_unrecorded_team.delay(self.identifier, self.title, team_id) + celery_send_mail_shared_data_unrecorded_team.delay(self.identifier, self.title, team_id, municipals_names) return action @@ -307,12 +309,13 @@ class RecordableObjectMixin(models.Model): shared_users = self.shared_users.values_list("id", flat=True) shared_teams = self.shared_teams.values_list("id", flat=True) + municipals_names = list(self.geometry.get_underlying_municipals().values_list("name", flat=True)) for user_id in shared_users: - celery_send_mail_shared_data_recorded.delay(self.identifier, self.title, user_id) + celery_send_mail_shared_data_recorded.delay(self.identifier, self.title, user_id, municipals_names) for team_id in shared_teams: - celery_send_mail_shared_data_recorded_team.delay(self.identifier, self.title, team_id) + celery_send_mail_shared_data_recorded_team.delay(self.identifier, self.title, team_id, municipals_names) return action @@ -404,15 +407,17 @@ class CheckableObjectMixin(models.Model): self.checked = action self.save() + municipals_names = list(self.geometry.get_underlying_municipals().values_list("name", flat=True)) + # Send mail shared_users = self.shared_users.values_list("id", flat=True) for user_id in shared_users: - celery_send_mail_shared_data_checked.delay(self.identifier, self.title, user_id) + celery_send_mail_shared_data_checked.delay(self.identifier, self.title, user_id, municipals_names) # Send mail shared_teams = self.shared_teams.values_list("id", flat=True) for team_id in shared_teams: - celery_send_mail_shared_data_checked_team.delay(self.identifier, self.title, team_id) + celery_send_mail_shared_data_checked_team.delay(self.identifier, self.title, team_id, municipals_names) self.log.add(action) return action @@ -574,10 +579,11 @@ class ShareableObjectMixin(models.Model): id__in=shared_teams ).values_list("id", flat=True) + municipals_names = list(self.geometry.get_underlying_municipals().values_list("name", flat=True)) for team_id in new_teams: - celery_send_mail_shared_access_given_team.delay(self.identifier, self.title, team_id) + celery_send_mail_shared_access_given_team.delay(self.identifier, self.title, team_id, municipals_names) for team_id in removed_teams: - celery_send_mail_shared_access_removed_team.delay(self.identifier, self.title, team_id) + celery_send_mail_shared_access_removed_team.delay(self.identifier, self.title, team_id, municipals_names) self.share_with_team_list(accessing_teams) @@ -602,11 +608,12 @@ class ShareableObjectMixin(models.Model): id__in=shared_users ).values_list("id", flat=True) + municipals_names = list(self.geometry.get_underlying_municipals().values_list("name", flat=True)) # Send mails for user_id in removed_users: - celery_send_mail_shared_access_removed.delay(self.identifier, self.title, user_id) + celery_send_mail_shared_access_removed.delay(self.identifier, self.title, user_id, municipals_names) for user_id in new_users: - celery_send_mail_shared_access_given.delay(self.identifier, self.title, user_id) + celery_send_mail_shared_access_given.delay(self.identifier, self.title, user_id, municipals_names) # Set new shared users self.share_with_user_list(accessing_users) @@ -669,8 +676,9 @@ class ShareableObjectMixin(models.Model): default_users.append(user) self.share_with_user_list(cleaned_users) + municipals_names = list(self.geometry.get_underlying_municipals().values_list("name", flat=True)) for user in default_users: - celery_send_mail_shared_access_removed.delay(self.identifier, self.title, user.id) + celery_send_mail_shared_access_removed.delay(self.identifier, self.title, user.id, municipals_names) class GeoReferencedMixin(models.Model): @@ -767,5 +775,6 @@ class ResubmitableObjectMixin(models.Model): """ resubmissions = self.resubmissions.all() + municipal_names = list(self.geometry.get_underlying_municipals().values_list("name", flat=True)) for resubmission in resubmissions: - resubmission.send_resubmission_mail(self.identifier) + resubmission.send_resubmission_mail(self.identifier, municipal_names) diff --git a/konova/models/resubmission.py b/konova/models/resubmission.py index be5fe84..e5fc714 100644 --- a/konova/models/resubmission.py +++ b/konova/models/resubmission.py @@ -31,7 +31,7 @@ class Resubmission(BaseResource): help_text="Optional comment for the user itself" ) - def send_resubmission_mail(self, obj_identifier): + def send_resubmission_mail(self, obj_identifier, municipal_names): """ Sends a resubmission mail """ @@ -41,6 +41,6 @@ class Resubmission(BaseResource): return mailer = Mailer() - mailer.send_mail_resubmission(obj_identifier, self) + mailer.send_mail_resubmission(obj_identifier, self, municipal_names) self.resubmission_sent = True self.save() diff --git a/konova/tasks.py b/konova/tasks.py index 99618fa..ab9e6af 100644 --- a/konova/tasks.py +++ b/konova/tasks.py @@ -25,87 +25,87 @@ def celery_update_parcels(geometry_id: str, recheck: bool = True): @shared_task -def celery_send_mail_shared_access_removed(obj_identifier, obj_title=None, user_id=None): +def celery_send_mail_shared_access_removed(obj_identifier, obj_title=None, user_id=None, municipals_names=[]): from user.models import User user = User.objects.get(id=user_id) - user.send_mail_shared_access_removed(obj_identifier, obj_title) + user.send_mail_shared_access_removed(obj_identifier, obj_title, municipals_names) @shared_task -def celery_send_mail_shared_access_given(obj_identifier, obj_title=None, user_id=None): +def celery_send_mail_shared_access_given(obj_identifier, obj_title=None, user_id=None, municipals_names=[]): from user.models import User user = User.objects.get(id=user_id) - user.send_mail_shared_access_given(obj_identifier, obj_title) + user.send_mail_shared_access_given(obj_identifier, obj_title, municipals_names) @shared_task -def celery_send_mail_shared_access_removed_team(obj_identifier, obj_title=None, team_id=None): +def celery_send_mail_shared_access_removed_team(obj_identifier, obj_title=None, team_id=None, municipals_names=[]): from user.models import Team team = Team.objects.get(id=team_id) - team.send_mail_shared_access_removed(obj_identifier, obj_title) + team.send_mail_shared_access_removed(obj_identifier, obj_title, municipals_names) @shared_task -def celery_send_mail_shared_access_given_team(obj_identifier, obj_title=None, team_id=None): +def celery_send_mail_shared_access_given_team(obj_identifier, obj_title=None, team_id=None, municipals_names=[]): from user.models import Team team = Team.objects.get(id=team_id) - team.send_mail_shared_access_given_team(obj_identifier, obj_title) + team.send_mail_shared_access_given_team(obj_identifier, obj_title, municipals_names) @shared_task -def celery_send_mail_shared_data_recorded(obj_identifier, obj_title=None, user_id=None): +def celery_send_mail_shared_data_recorded(obj_identifier, obj_title=None, user_id=None, municipals_names=[]): from user.models import User user = User.objects.get(id=user_id) - user.send_mail_shared_data_recorded(obj_identifier, obj_title) + user.send_mail_shared_data_recorded(obj_identifier, obj_title, municipals_names) @shared_task -def celery_send_mail_shared_data_unrecorded(obj_identifier, obj_title=None, user_id=None): +def celery_send_mail_shared_data_unrecorded(obj_identifier, obj_title=None, user_id=None, municipals_names=[]): from user.models import User user = User.objects.get(id=user_id) - user.send_mail_shared_data_unrecorded(obj_identifier, obj_title) + user.send_mail_shared_data_unrecorded(obj_identifier, obj_title, municipals_names) @shared_task -def celery_send_mail_shared_data_recorded_team(obj_identifier, obj_title=None, team_id=None): +def celery_send_mail_shared_data_recorded_team(obj_identifier, obj_title=None, team_id=None, municipals_names=[]): from user.models import Team team = Team.objects.get(id=team_id) - team.send_mail_shared_data_recorded(obj_identifier, obj_title) + team.send_mail_shared_data_recorded(obj_identifier, obj_title, municipals_names) @shared_task -def celery_send_mail_shared_data_unrecorded_team(obj_identifier, obj_title=None, team_id=None): +def celery_send_mail_shared_data_unrecorded_team(obj_identifier, obj_title=None, team_id=None, municipals_names=[]): from user.models import Team team = Team.objects.get(id=team_id) - team.send_mail_shared_data_unrecorded(obj_identifier, obj_title) + team.send_mail_shared_data_unrecorded(obj_identifier, obj_title, municipals_names) @shared_task -def celery_send_mail_shared_data_deleted(obj_identifier, obj_title=None, user_id=None): +def celery_send_mail_shared_data_deleted(obj_identifier, obj_title=None, user_id=None, municipals_names=[]): from user.models import User user = User.objects.get(id=user_id) - user.send_mail_shared_data_deleted(obj_identifier, obj_title) + user.send_mail_shared_data_deleted(obj_identifier, obj_title, municipals_names) @shared_task -def celery_send_mail_shared_data_checked(obj_identifier, obj_title=None, user_id=None): +def celery_send_mail_shared_data_checked(obj_identifier, obj_title=None, user_id=None, municipals_names=[]): from user.models import User user = User.objects.get(id=user_id) - user.send_mail_shared_data_checked(obj_identifier, obj_title) + user.send_mail_shared_data_checked(obj_identifier, obj_title, municipals_names) @shared_task -def celery_send_mail_shared_data_deleted_team(obj_identifier, obj_title=None, team_id=None): +def celery_send_mail_shared_data_deleted_team(obj_identifier, obj_title=None, team_id=None, municipals_names=[]): from user.models import Team team = Team.objects.get(id=team_id) - team.send_mail_shared_data_deleted(obj_identifier, obj_title) + team.send_mail_shared_data_deleted(obj_identifier, obj_title, municipals_names) @shared_task -def celery_send_mail_shared_data_checked_team(obj_identifier, obj_title=None, team_id=None): +def celery_send_mail_shared_data_checked_team(obj_identifier, obj_title=None, team_id=None, municipals_names=[]): from user.models import Team team = Team.objects.get(id=team_id) - team.send_mail_shared_data_checked(obj_identifier, obj_title) + team.send_mail_shared_data_checked(obj_identifier, obj_title, municipals_names) @shared_task diff --git a/konova/utils/mailer.py b/konova/utils/mailer.py index 5c25d84..faf21fd 100644 --- a/konova/utils/mailer.py +++ b/konova/utils/mailer.py @@ -45,12 +45,14 @@ class Mailer: auth_password=self.auth_password ) - def send_mail_shared_access_removed(self, obj_identifier, obj_title, user): + def send_mail_shared_access_removed(self, obj_identifier, obj_title, user, municipals_names): """ Send a mail if user has no access to the object anymore Args: obj_identifier (str): The object identifier obj_title (str): The object title + user (User): Related user + municipals_names (iterable): List of municipals of the entry Returns: @@ -59,6 +61,7 @@ class Mailer: "user": user, "obj_identifier": obj_identifier, "obj_title": obj_title, + "municipals_names": municipals_names, "EMAIL_REPLY_TO": EMAIL_REPLY_TO, } msg = render_to_string("email/sharing/shared_access_removed.html", context) @@ -69,11 +72,14 @@ class Mailer: msg ) - def send_mail_shared_access_given(self, obj_identifier, obj_title, user): + def send_mail_shared_access_given(self, obj_identifier, obj_title, user, municipals_names): """ Send a mail if user just got access to the object Args: obj_identifier (str): The object identifier + obj_title (str): The object title + user (User): The related user + municipals_names (iterable): List of municipals for this entry Returns: @@ -82,6 +88,7 @@ class Mailer: "user": user, "obj_identifier": obj_identifier, "obj_title": obj_title, + "municipals_names": municipals_names, "EMAIL_REPLY_TO": EMAIL_REPLY_TO, } msg = render_to_string("email/sharing/shared_access_given.html", context) @@ -92,7 +99,7 @@ class Mailer: msg ) - def send_mail_shared_access_given_team(self, obj_identifier, obj_title, team, users_to_notify): + def send_mail_shared_access_given_team(self, obj_identifier, obj_title, team, users_to_notify, municipals_names): """ Send a mail if a team just got access to the object Args: @@ -100,6 +107,7 @@ class Mailer: obj_title (str): Title of the main object team (Team): Team to be notified users_to_notify (QueryDict): Contains the team users which should be notified + municipals_names (iterable): List of municipals for this entry Returns: @@ -108,6 +116,7 @@ class Mailer: "team": team, "obj_identifier": obj_identifier, "obj_title": obj_title, + "municipals_names": municipals_names, "EMAIL_REPLY_TO": EMAIL_REPLY_TO, } msg = render_to_string("email/sharing/shared_access_given_team.html", context) @@ -118,7 +127,7 @@ class Mailer: msg ) - def send_mail_shared_access_removed_team(self, obj_identifier, obj_title, team, users_to_notify): + def send_mail_shared_access_removed_team(self, obj_identifier, obj_title, team, users_to_notify, municipals_names): """ Send a mail if a team just lost access to the object Args: @@ -126,6 +135,7 @@ class Mailer: obj_title (str): Title of the main object team (Team): Team to be notified users_to_notify (QueryDict): Contains the team users which should be notified + municipals_names (iterable): List of municipals for this entry Returns: @@ -134,6 +144,7 @@ class Mailer: "team": team, "obj_identifier": obj_identifier, "obj_title": obj_title, + "municipals_names": municipals_names, "EMAIL_REPLY_TO": EMAIL_REPLY_TO, } msg = render_to_string("email/sharing/shared_access_removed_team.html", context) @@ -144,7 +155,7 @@ class Mailer: msg ) - def send_mail_shared_data_unrecorded_team(self, obj_identifier, obj_title, team, users_to_notify): + def send_mail_shared_data_unrecorded_team(self, obj_identifier, obj_title, team, users_to_notify, municipals_names): """ Send a mail if data has just been unrecorded Args: @@ -152,6 +163,7 @@ class Mailer: obj_title (str): Title of the main object team (Team): Team to be notified users_to_notify (QueryDict): Contains the team users which should be notified + municipals_names (iterable): List of municipals for this entry Returns: @@ -160,6 +172,7 @@ class Mailer: "team": team, "obj_identifier": obj_identifier, "obj_title": obj_title, + "municipals_names": municipals_names, "EMAIL_REPLY_TO": EMAIL_REPLY_TO, } msg = render_to_string("email/recording/shared_data_unrecorded_team.html", context) @@ -170,7 +183,7 @@ class Mailer: msg ) - def send_mail_shared_data_recorded_team(self, obj_identifier, obj_title, team, users_to_notify): + def send_mail_shared_data_recorded_team(self, obj_identifier, obj_title, team, users_to_notify, municipals_names): """ Send a mail if data has just been recorded Args: @@ -178,6 +191,7 @@ class Mailer: obj_title (str): Title of the main object team (Team): Team to be notified users_to_notify (QueryDict): Contains the team users which should be notified + municipals_names (iterable): List of municipals for this entry Returns: @@ -186,6 +200,7 @@ class Mailer: "team": team, "obj_identifier": obj_identifier, "obj_title": obj_title, + "municipals_names": municipals_names, "EMAIL_REPLY_TO": EMAIL_REPLY_TO, } msg = render_to_string("email/recording/shared_data_recorded_team.html", context) @@ -196,7 +211,7 @@ class Mailer: msg ) - def send_mail_shared_data_checked_team(self, obj_identifier, obj_title, team, users_to_notify): + def send_mail_shared_data_checked_team(self, obj_identifier, obj_title, team, users_to_notify, municipals_names): """ Send a mail if data has just been checked Args: @@ -204,6 +219,7 @@ class Mailer: obj_title (str): Title of the main object team (Team): Team to be notified users_to_notify (QueryDict): Contains the team users which should be notified + municipals_names (iterable): List of municipals for this entry Returns: @@ -212,6 +228,7 @@ class Mailer: "team": team, "obj_identifier": obj_identifier, "obj_title": obj_title, + "municipals_names": municipals_names, "EMAIL_REPLY_TO": EMAIL_REPLY_TO, } msg = render_to_string("email/checking/shared_data_checked_team.html", context) @@ -249,11 +266,15 @@ class Mailer: msg ) - def send_mail_shared_data_deleted_team(self, obj_identifier, obj_title, team, users_to_notify): + def send_mail_shared_data_deleted_team(self, obj_identifier, obj_title, team, users_to_notify, municipals_names): """ Send a mail if data has just been deleted Args: obj_identifier (str): The object identifier + obj_title (str): The object title + team (Team): The related team + users_to_notify (QuerySet): Contains team users who want to be notified + municipals_names (iterable): List of municipals for the entry Returns: @@ -262,6 +283,7 @@ class Mailer: "team": team, "obj_identifier": obj_identifier, "obj_title": obj_title, + "municipals_names": municipals_names, "EMAIL_REPLY_TO": EMAIL_REPLY_TO, } msg = render_to_string("email/deleting/shared_data_deleted_team.html", context) @@ -272,11 +294,14 @@ class Mailer: msg ) - def send_mail_shared_data_recorded(self, obj_identifier, obj_title, user): + def send_mail_shared_data_recorded(self, obj_identifier, obj_title, user, municipals_names): """ Send a mail if the user's shared data has just been unrecorded Args: obj_identifier (str): The object identifier + obj_title (str): The object title + user (User): The related user + municipals_names (iterable): List of municipals for this entry Returns: @@ -285,6 +310,7 @@ class Mailer: "user": user, "obj_identifier": obj_identifier, "obj_title": obj_title, + "municipals_names": municipals_names, "EMAIL_REPLY_TO": EMAIL_REPLY_TO, } msg = render_to_string("email/recording/shared_data_recorded.html", context) @@ -295,11 +321,14 @@ class Mailer: msg ) - def send_mail_shared_data_unrecorded(self, obj_identifier, obj_title, user): + def send_mail_shared_data_unrecorded(self, obj_identifier, obj_title, user, municipals_names): """ Send a mail if the user's shared data has just been unrecorded Args: obj_identifier (str): The object identifier + obj_title (str): The object title + user (User): The related user + municipals_names (iterable): List of municipals for this entry Returns: @@ -308,6 +337,7 @@ class Mailer: "user": user, "obj_identifier": obj_identifier, "obj_title": obj_title, + "municipals_names": municipals_names, "EMAIL_REPLY_TO": EMAIL_REPLY_TO, } msg = render_to_string("email/recording/shared_data_unrecorded.html", context) @@ -318,11 +348,14 @@ class Mailer: msg ) - def send_mail_shared_data_deleted(self, obj_identifier, obj_title, user): + def send_mail_shared_data_deleted(self, obj_identifier, obj_title, user, municipals_names): """ Send a mail if shared data has just been deleted Args: obj_identifier (str): The object identifier + obj_title (str): The object title + user (User): The related user + municipals_names (iterable): List of municipals for this entry Returns: @@ -331,6 +364,7 @@ class Mailer: "user": user, "obj_identifier": obj_identifier, "obj_title": obj_title, + "municipals_names": municipals_names, "EMAIL_REPLY_TO": EMAIL_REPLY_TO, } msg = render_to_string("email/deleting/shared_data_deleted.html", context) @@ -341,11 +375,14 @@ class Mailer: msg ) - def send_mail_shared_data_checked(self, obj_identifier, obj_title, user): + def send_mail_shared_data_checked(self, obj_identifier, obj_title, user, municipals_names): """ Send a mail if shared data just has been checked Args: obj_identifier (str): The object identifier + obj_title (str): The object title + user (User): The related user + municipals_names (iterable): List of municipals for this entry Returns: @@ -354,6 +391,7 @@ class Mailer: "user": user, "obj_identifier": obj_identifier, "obj_title": obj_title, + "municipals_names": municipals_names, "EMAIL_REPLY_TO": EMAIL_REPLY_TO, } msg = render_to_string("email/checking/shared_data_checked.html", context) @@ -413,12 +451,13 @@ class Mailer: msg ) - def send_mail_resubmission(self, obj_identifier, resubmission): + def send_mail_resubmission(self, obj_identifier, resubmission, municipals_names): """ Send a resubmission mail for a user Args: obj_identifier (str): The (resubmitted) object's identifier resubmission (Resubmission): The resubmission + municipals_names (iterable): List of municipals for this entry Returns: @@ -426,6 +465,7 @@ class Mailer: context = { "obj_identifier": obj_identifier, "resubmission": resubmission, + "municipals_names": municipals_names, "EMAIL_REPLY_TO": EMAIL_REPLY_TO, } msg = render_to_string("email/resubmission/resubmission.html", context) diff --git a/konova/views/geometry.py b/konova/views/geometry.py index 7d7fa6e..f22b9c1 100644 --- a/konova/views/geometry.py +++ b/konova/views/geometry.py @@ -44,9 +44,7 @@ def get_geom_parcels(request: HttpRequest, id: str): status_code = 200 if parcels_available or not geometry_exists: - parcels = parcels.order_by("-municipal", "flr", "flrstck_zhlr", "flrstck_nnr") - municipals = parcels.order_by("municipal").distinct("municipal").values("municipal__id") - municipals = Municipal.objects.filter(id__in=municipals) + municipals = geom.get_underlying_municipals(parcels) rpp = 100 num_all_parcels = parcels.count() diff --git a/locale/de/LC_MESSAGES/django.mo b/locale/de/LC_MESSAGES/django.mo index 1eca329178daacf6c62e36e07429631dd25732c1..40369ea975fea21ac7e278be7244fd231db4e9f8 100644 GIT binary patch delta 10648 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 delta 10481 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 Rw?6fH%YdyH-#B0H{{X19m+}Ar diff --git a/locale/de/LC_MESSAGES/django.po b/locale/de/LC_MESSAGES/django.po index c225fa4..4164f73 100644 --- a/locale/de/LC_MESSAGES/django.po +++ b/locale/de/LC_MESSAGES/django.po @@ -9,8 +9,8 @@ #: compensation/forms/modals/payment.py:23 #: compensation/forms/modals/payment.py:34 #: compensation/forms/modals/payment.py:50 -#: intervention/forms/intervention.py:55 intervention/forms/intervention.py:175 -#: intervention/forms/intervention.py:187 +#: intervention/forms/intervention.py:56 intervention/forms/intervention.py:176 +#: intervention/forms/intervention.py:188 #: intervention/forms/modals/revocation.py:20 #: intervention/forms/modals/revocation.py:33 #: intervention/forms/modals/revocation.py:46 @@ -43,7 +43,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-12-06 08:23+0100\n" +"POT-Creation-Date: 2023-02-23 08:48+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -74,7 +74,7 @@ msgstr "Einträge erstellt bis..." #: compensation/templates/compensation/report/eco_account/report.html:16 #: compensation/utils/quality.py:111 ema/templates/ema/detail/view.html:49 #: ema/templates/ema/report/report.html:16 ema/utils/quality.py:26 -#: intervention/forms/intervention.py:103 +#: intervention/forms/intervention.py:104 #: intervention/templates/intervention/detail/view.html:56 #: intervention/templates/intervention/report/report.html:37 #: intervention/utils/quality.py:62 konova/filters/mixins/office.py:34 @@ -85,11 +85,11 @@ msgstr "Eintragungsstelle" msgid "Select the responsible office" msgstr "Verantwortliche Stelle" -#: analysis/forms.py:60 compensation/forms/compensation.py:93 +#: analysis/forms.py:60 compensation/forms/compensation.py:94 #: compensation/forms/mixins.py:32 compensation/forms/mixins.py:62 -#: intervention/forms/intervention.py:65 intervention/forms/intervention.py:82 -#: intervention/forms/intervention.py:98 intervention/forms/intervention.py:114 -#: intervention/forms/intervention.py:155 intervention/forms/modals/share.py:41 +#: intervention/forms/intervention.py:66 intervention/forms/intervention.py:83 +#: intervention/forms/intervention.py:99 intervention/forms/intervention.py:115 +#: intervention/forms/intervention.py:156 intervention/forms/modals/share.py:41 #: intervention/forms/modals/share.py:55 user/forms/modals/team.py:48 #: user/forms/modals/team.py:112 msgid "Click for selection" @@ -309,7 +309,7 @@ msgstr "" " " #: analysis/templates/analysis/reports/includes/intervention/laws.html:14 -#: intervention/forms/intervention.py:70 +#: intervention/forms/intervention.py:71 #: intervention/templates/intervention/detail/view.html:39 #: intervention/templates/intervention/report/report.html:20 msgid "Law" @@ -368,7 +368,7 @@ msgstr "Kennung" msgid "Generated automatically - not editable" msgstr "Automatisch generiert - nicht bearbeitbar" -#: compensation/forms/compensation.py:42 compensation/tables/compensation.py:28 +#: compensation/forms/compensation.py:43 compensation/tables/compensation.py:28 #: compensation/tables/eco_account.py:28 #: compensation/templates/compensation/detail/compensation/includes/documents.html:28 #: compensation/templates/compensation/detail/compensation/view.html:32 @@ -379,7 +379,7 @@ msgstr "Automatisch generiert - nicht bearbeitbar" #: ema/tables.py:31 ema/templates/ema/detail/includes/documents.html:28 #: ema/templates/ema/detail/view.html:31 #: ema/templates/ema/report/report.html:12 -#: intervention/forms/intervention.py:41 intervention/tables.py:28 +#: intervention/forms/intervention.py:42 intervention/tables.py:28 #: intervention/templates/intervention/detail/includes/compensations.html:33 #: intervention/templates/intervention/detail/includes/documents.html:33 #: intervention/templates/intervention/detail/view.html:31 @@ -388,15 +388,15 @@ msgstr "Automatisch generiert - nicht bearbeitbar" msgid "Title" msgstr "Bezeichnung" -#: compensation/forms/compensation.py:44 intervention/forms/intervention.py:43 +#: compensation/forms/compensation.py:45 intervention/forms/intervention.py:44 msgid "An explanatory name" msgstr "Aussagekräftiger Titel" -#: compensation/forms/compensation.py:48 ema/forms.py:51 ema/forms.py:114 +#: compensation/forms/compensation.py:49 ema/forms.py:51 ema/forms.py:114 msgid "Compensation XY; Location ABC" msgstr "Kompensation XY; Flur ABC" -#: compensation/forms/compensation.py:55 +#: compensation/forms/compensation.py:56 #: compensation/forms/modals/compensation_action.py:81 #: compensation/forms/modals/deadline.py:49 #: compensation/forms/modals/payment.py:49 @@ -409,7 +409,7 @@ msgstr "Kompensation XY; Flur ABC" #: ema/templates/ema/detail/includes/actions.html:34 #: ema/templates/ema/detail/includes/deadlines.html:39 #: ema/templates/ema/detail/includes/documents.html:34 -#: intervention/forms/intervention.py:199 +#: intervention/forms/intervention.py:200 #: intervention/forms/modals/revocation.py:45 #: intervention/templates/intervention/detail/includes/documents.html:39 #: intervention/templates/intervention/detail/includes/payments.html:34 @@ -420,29 +420,29 @@ msgstr "Kompensation XY; Flur ABC" msgid "Comment" msgstr "Kommentar" -#: compensation/forms/compensation.py:57 +#: compensation/forms/compensation.py:58 #: compensation/forms/modals/compensation_action.py:83 -#: intervention/forms/intervention.py:201 +#: intervention/forms/intervention.py:202 #: konova/forms/modals/resubmission_form.py:37 msgid "Additional comment" msgstr "Zusätzlicher Kommentar" -#: compensation/forms/compensation.py:84 +#: compensation/forms/compensation.py:85 #: compensation/templates/compensation/detail/compensation/view.html:36 #: compensation/templates/compensation/report/compensation/report.html:16 msgid "compensates intervention" msgstr "kompensiert Eingriff" -#: compensation/forms/compensation.py:86 +#: compensation/forms/compensation.py:87 msgid "Select the intervention for which this compensation compensates" msgstr "Wählen Sie den Eingriff, für den diese Kompensation bestimmt ist" -#: compensation/forms/compensation.py:113 +#: compensation/forms/compensation.py:114 #: compensation/views/compensation/compensation.py:115 msgid "New compensation" msgstr "Neue Kompensation" -#: compensation/forms/compensation.py:189 +#: compensation/forms/compensation.py:190 msgid "Edit compensation" msgstr "Bearbeite Kompensation" @@ -488,14 +488,14 @@ msgstr "" #: compensation/templates/compensation/report/eco_account/report.html:20 #: compensation/utils/quality.py:113 ema/templates/ema/detail/view.html:53 #: ema/templates/ema/report/report.html:20 ema/utils/quality.py:28 -#: intervention/forms/intervention.py:131 +#: intervention/forms/intervention.py:132 #: intervention/templates/intervention/detail/view.html:60 #: intervention/templates/intervention/report/report.html:41 #: intervention/utils/quality.py:55 msgid "Conservation office file number" msgstr "Aktenzeichen Eintragungsstelle" -#: compensation/forms/mixins.py:43 intervention/forms/intervention.py:137 +#: compensation/forms/mixins.py:43 intervention/forms/intervention.py:138 msgid "ETS-123/ABC.456" msgstr "" @@ -511,11 +511,11 @@ msgstr "Zu welcher Kategorie dieser Maßnahmenträger gehört" msgid "Eco-Account handler detail" msgstr "Detailangabe zum Maßnahmenträger" -#: compensation/forms/mixins.py:71 intervention/forms/intervention.py:164 +#: compensation/forms/mixins.py:71 intervention/forms/intervention.py:165 msgid "Detail input on the handler" msgstr "Name der Behörde, Stadt, Firma, ..." -#: compensation/forms/mixins.py:74 intervention/forms/intervention.py:167 +#: compensation/forms/mixins.py:74 intervention/forms/intervention.py:168 msgid "Company Mustermann" msgstr "Firma Mustermann" @@ -1284,7 +1284,7 @@ msgstr "Kompensation {} bearbeitet" #: compensation/views/compensation/compensation.py:187 #: compensation/views/eco_account/eco_account.py:161 ema/views/ema.py:212 -#: intervention/views/intervention.py:230 +#: intervention/views/intervention.py:231 msgid "Edit {}" msgstr "Bearbeite {}" @@ -1306,7 +1306,7 @@ msgstr "Ökokonto {} hinzugefügt" msgid "Eco-Account {} edited" msgstr "Ökokonto {} bearbeitet" -#: compensation/views/eco_account/eco_account.py:267 +#: compensation/views/eco_account/eco_account.py:268 msgid "Eco-account removed" msgstr "Ökokonto entfernt" @@ -1354,70 +1354,70 @@ msgstr "EMA {} bearbeitet" msgid "EMA removed" msgstr "EMA entfernt" -#: intervention/forms/intervention.py:47 +#: intervention/forms/intervention.py:48 msgid "Construction XY; Location ABC" msgstr "Bauvorhaben XY; Flur ABC" -#: intervention/forms/intervention.py:53 +#: intervention/forms/intervention.py:54 #: intervention/templates/intervention/detail/view.html:35 #: intervention/templates/intervention/report/report.html:16 #: intervention/utils/quality.py:95 msgid "Process type" msgstr "Verfahrenstyp" -#: intervention/forms/intervention.py:72 +#: intervention/forms/intervention.py:73 msgid "Multiple selection possible" msgstr "Mehrfachauswahl möglich" -#: intervention/forms/intervention.py:87 +#: intervention/forms/intervention.py:88 #: intervention/templates/intervention/detail/view.html:48 #: intervention/templates/intervention/report/report.html:29 #: intervention/utils/quality.py:59 konova/filters/mixins/office.py:66 msgid "Registration office" msgstr "Zulassungsbehörde" -#: intervention/forms/intervention.py:119 +#: intervention/forms/intervention.py:120 #: intervention/templates/intervention/detail/view.html:52 #: intervention/templates/intervention/report/report.html:33 #: intervention/utils/quality.py:52 msgid "Registration office file number" msgstr "Aktenzeichen Zulassungsbehörde" -#: intervention/forms/intervention.py:125 +#: intervention/forms/intervention.py:126 msgid "ZB-123/ABC.456" msgstr "" -#: intervention/forms/intervention.py:143 +#: intervention/forms/intervention.py:144 msgid "Intervention handler type" msgstr "Art des Eingriffsverursachers" -#: intervention/forms/intervention.py:145 +#: intervention/forms/intervention.py:146 msgid "What type of handler is responsible for the intervention?" msgstr "Zu welcher Kategorie dieser Eingriffsverursacher gehört" -#: intervention/forms/intervention.py:160 +#: intervention/forms/intervention.py:161 msgid "Intervention handler detail" msgstr "Detailangabe zum Eingriffsverursacher" -#: intervention/forms/intervention.py:174 +#: intervention/forms/intervention.py:175 #: intervention/templates/intervention/detail/view.html:101 #: intervention/templates/intervention/report/report.html:81 #: intervention/utils/quality.py:86 msgid "Registration date" msgstr "Datum Zulassung bzw. Satzungsbeschluss" -#: intervention/forms/intervention.py:186 +#: intervention/forms/intervention.py:187 #: intervention/templates/intervention/detail/view.html:105 #: intervention/templates/intervention/report/report.html:85 msgid "Binding on" msgstr "Datum Bestandskraft bzw. Rechtskraft" -#: intervention/forms/intervention.py:212 +#: intervention/forms/intervention.py:213 #: intervention/views/intervention.py:100 msgid "New intervention" msgstr "Neuer Eingriff" -#: intervention/forms/intervention.py:302 +#: intervention/forms/intervention.py:303 msgid "Edit intervention" msgstr "Eingriff bearbeiten" @@ -1653,11 +1653,11 @@ msgstr "Eingriffe - Übersicht" msgid "Intervention {} added" msgstr "Eingriff {} hinzugefügt" -#: intervention/views/intervention.py:218 +#: intervention/views/intervention.py:219 msgid "Intervention {} edited" msgstr "Eingriff {} bearbeitet" -#: intervention/views/intervention.py:255 +#: intervention/views/intervention.py:256 msgid "{} removed" msgstr "{} entfernt" @@ -1744,7 +1744,8 @@ msgstr "Verzeichnete anzeigen" #: konova/filters/mixins/record.py:27 msgid "If activated also shows entries which have been already recorded" -msgstr "Wenn aktiviert werden auch Einträge angezeigt, die bereits verzeichnet wurden" +msgstr "" +"Wenn aktiviert werden auch Einträge angezeigt, die bereits verzeichnet wurden" #: konova/filters/mixins/self_created.py:23 msgid "Show only self created" @@ -1752,7 +1753,9 @@ msgstr "Nur selbst erstellte anzeigen" #: konova/filters/mixins/self_created.py:28 msgid "If activated only shows entries which have been created by you" -msgstr "Wenn aktiviert werden nur Einträge angezeigt, die von Ihnen erstellt worden sind" +msgstr "" +"Wenn aktiviert werden nur Einträge angezeigt, die von Ihnen erstellt worden " +"sind" #: konova/filters/mixins/share.py:22 msgid "Show unshared" @@ -1760,13 +1763,15 @@ msgstr "Nicht freigegebene anzeigen" #: konova/filters/mixins/share.py:27 msgid "If activated also shows entries which are not shared with you" -msgstr "Wenn aktiviert werden auch Einträge angezeigt, die nicht für Sie freigegeben sind" +msgstr "" +"Wenn aktiviert werden auch Einträge angezeigt, die nicht für Sie freigegeben " +"sind" #: konova/forms/base_form.py:23 templates/form/collapsable/form.html:62 msgid "Save" msgstr "Speichern" -#: konova/forms/base_form.py:57 +#: konova/forms/base_form.py:72 msgid "Not editable" msgstr "Nicht editierbar" @@ -1822,11 +1827,11 @@ msgstr "" msgid "Confirm" msgstr "Bestätige" -#: konova/forms/modals/remove_form.py:31 konova/forms/remove_form.py:30 +#: konova/forms/modals/remove_form.py:32 konova/forms/remove_form.py:30 msgid "Remove" msgstr "Löschen" -#: konova/forms/modals/remove_form.py:32 +#: konova/forms/modals/remove_form.py:33 msgid "Are you sure?" msgstr "Sind Sie sicher?" @@ -1976,39 +1981,39 @@ msgstr "In Zwischenablage kopiert" msgid "Search" msgstr "Suchen" -#: konova/utils/mailer.py:68 konova/utils/mailer.py:143 +#: konova/utils/mailer.py:71 konova/utils/mailer.py:154 msgid "{} - Shared access removed" msgstr "{} - Zugriff entzogen" -#: konova/utils/mailer.py:91 konova/utils/mailer.py:117 +#: konova/utils/mailer.py:98 konova/utils/mailer.py:126 msgid "{} - Shared access given" msgstr "{} - Zugriff freigegeben" -#: konova/utils/mailer.py:169 konova/utils/mailer.py:317 +#: konova/utils/mailer.py:182 konova/utils/mailer.py:346 msgid "{} - Shared data unrecorded" msgstr "{} - Freigegebene Daten entzeichnet" -#: konova/utils/mailer.py:195 konova/utils/mailer.py:294 +#: konova/utils/mailer.py:210 konova/utils/mailer.py:319 msgid "{} - Shared data recorded" msgstr "{} - Freigegebene Daten verzeichnet" -#: konova/utils/mailer.py:221 konova/utils/mailer.py:363 +#: konova/utils/mailer.py:238 konova/utils/mailer.py:400 msgid "{} - Shared data checked" msgstr "{} - Freigegebene Daten geprüft" -#: konova/utils/mailer.py:248 konova/utils/mailer.py:391 +#: konova/utils/mailer.py:265 konova/utils/mailer.py:428 msgid "{} - Deduction changed" msgstr "{} - Abbuchung geändert" -#: konova/utils/mailer.py:271 konova/utils/mailer.py:340 +#: konova/utils/mailer.py:293 konova/utils/mailer.py:373 msgid "{} - Shared data deleted" msgstr "{} - Freigegebene Daten gelöscht" -#: konova/utils/mailer.py:412 templates/email/api/verify_token.html:4 +#: konova/utils/mailer.py:449 templates/email/api/verify_token.html:4 msgid "Request for new API token" msgstr "Anfrage für neuen API Token" -#: konova/utils/mailer.py:435 +#: konova/utils/mailer.py:474 msgid "Resubmission - {}" msgstr "Wiedervorlage - {}" @@ -2369,7 +2374,7 @@ msgstr "" #: templates/email/recording/shared_data_unrecorded.html:20 #: templates/email/recording/shared_data_unrecorded_team.html:20 #: templates/email/resubmission/resubmission.html:21 -#: templates/email/sharing/shared_access_given.html:21 +#: templates/email/sharing/shared_access_given.html:29 #: templates/email/sharing/shared_access_given_team.html:21 #: templates/email/sharing/shared_access_removed.html:21 #: templates/email/sharing/shared_access_removed_team.html:21 @@ -2535,11 +2540,19 @@ msgid "the following dataset has just been shared with you" msgstr "der folgende Datensatz wurde soeben für Sie freigegeben " #: templates/email/sharing/shared_access_given.html:17 +msgid "This entry is located in" +msgstr "Dieser Eintrag befindet sich in" + +#: templates/email/sharing/shared_access_given.html:23 +msgid "Unknown - No administrative location recognized" +msgstr "Unbekannt - Keine administrative Verortung möglich" + +#: templates/email/sharing/shared_access_given.html:25 #: templates/email/sharing/shared_access_given_team.html:17 msgid "This means you can now edit this dataset." msgstr "Das bedeutet, dass Sie diesen Datensatz nun auch bearbeiten können." -#: templates/email/sharing/shared_access_given.html:18 +#: templates/email/sharing/shared_access_given.html:26 #: templates/email/sharing/shared_access_given_team.html:18 msgid "" "The shared dataset appears now by default on your overview for this dataset " @@ -2548,7 +2561,7 @@ msgstr "" "Der freigegebene Datensatz ist nun standardmäßig in Ihrer Übersicht für den " "Datensatztyp im KSP gelistet." -#: templates/email/sharing/shared_access_given.html:28 +#: templates/email/sharing/shared_access_given.html:36 #: templates/email/sharing/shared_access_given_team.html:28 msgid "" "Please note: Shared access on an intervention means you automatically have " @@ -2665,7 +2678,7 @@ msgstr "" "Vergessen Sie nicht ihn anschließend wieder zu verzeichnen.\n" " " -#: templates/form/table/generic_table_form_body.html:24 +#: templates/form/table/generic_table_form_body.html:30 msgid "Fields with * are required." msgstr "* sind Pflichtfelder." diff --git a/templates/email/checking/shared_data_checked.html b/templates/email/checking/shared_data_checked.html index 133dae2..258315d 100644 --- a/templates/email/checking/shared_data_checked.html +++ b/templates/email/checking/shared_data_checked.html @@ -14,6 +14,16 @@
{{obj_title}}
+
+ {% trans 'This entry is located in' %} +
    + {% for municipal in municipals_names %} +
  • {{municipal}}
  • + {% empty %} +
+ {% trans 'Unknown - No administrative location recognized' %} + {% endfor %} + {% trans 'This means, the responsible registration office just confirmed the correctness of this dataset.' %}

diff --git a/templates/email/checking/shared_data_checked_team.html b/templates/email/checking/shared_data_checked_team.html index 6a7a450..6d02df5 100644 --- a/templates/email/checking/shared_data_checked_team.html +++ b/templates/email/checking/shared_data_checked_team.html @@ -14,6 +14,16 @@
{{obj_title}}
+
+ {% trans 'This entry is located in' %} +
    + {% for municipal in municipals_names %} +
  • {{municipal}}
  • + {% empty %} +
+ {% trans 'Unknown - No administrative location recognized' %} + {% endfor %} + {% trans 'This means, the responsible registration office just confirmed the correctness of this dataset.' %}

diff --git a/templates/email/deleting/shared_data_deleted.html b/templates/email/deleting/shared_data_deleted.html index 7857444..491e70b 100644 --- a/templates/email/deleting/shared_data_deleted.html +++ b/templates/email/deleting/shared_data_deleted.html @@ -14,6 +14,16 @@
"{{obj_title}}"
+
+ {% trans 'This entry is located in' %} +
    + {% for municipal in municipals_names %} +
  • {{municipal}}
  • + {% empty %} +
+ {% trans 'Unknown - No administrative location recognized' %} + {% endfor %} + {% trans 'If this should not have been happened, please contact us. See the signature for details.' %}

diff --git a/templates/email/deleting/shared_data_deleted_team.html b/templates/email/deleting/shared_data_deleted_team.html index 0ffa8bb..ba1328d 100644 --- a/templates/email/deleting/shared_data_deleted_team.html +++ b/templates/email/deleting/shared_data_deleted_team.html @@ -14,6 +14,16 @@
"{{obj_title}}"
+
+ {% trans 'This entry is located in' %} +
    + {% for municipal in municipals_names %} +
  • {{municipal}}
  • + {% empty %} +
+ {% trans 'Unknown - No administrative location recognized' %} + {% endfor %} + {% trans 'If this should not have been happened, please contact us. See the signature for details.' %}

diff --git a/templates/email/recording/shared_data_recorded.html b/templates/email/recording/shared_data_recorded.html index ccad11e..71f92f7 100644 --- a/templates/email/recording/shared_data_recorded.html +++ b/templates/email/recording/shared_data_recorded.html @@ -14,6 +14,16 @@
"{{obj_title}}"
+
+ {% trans 'This entry is located in' %} +
    + {% for municipal in municipals_names %} +
  • {{municipal}}
  • + {% empty %} +
+ {% trans 'Unknown - No administrative location recognized' %} + {% endfor %} + {% trans 'This means the data is now publicly available, e.g. in LANIS' %}

diff --git a/templates/email/recording/shared_data_recorded_team.html b/templates/email/recording/shared_data_recorded_team.html index 0734bc6..1c84674 100644 --- a/templates/email/recording/shared_data_recorded_team.html +++ b/templates/email/recording/shared_data_recorded_team.html @@ -14,6 +14,16 @@
"{{obj_title}}"
+
+ {% trans 'This entry is located in' %} +
    + {% for municipal in municipals_names %} +
  • {{municipal}}
  • + {% empty %} +
+ {% trans 'Unknown - No administrative location recognized' %} + {% endfor %} + {% trans 'This means the data is now publicly available, e.g. in LANIS' %}

diff --git a/templates/email/recording/shared_data_unrecorded.html b/templates/email/recording/shared_data_unrecorded.html index 3406b75..c6c7b0c 100644 --- a/templates/email/recording/shared_data_unrecorded.html +++ b/templates/email/recording/shared_data_unrecorded.html @@ -14,6 +14,16 @@
"{{obj_title}}"
+
+ {% trans 'This entry is located in' %} +
    + {% for municipal in municipals_names %} +
  • {{municipal}}
  • + {% empty %} +
+ {% trans 'Unknown - No administrative location recognized' %} + {% endfor %} + {% trans 'This means the data is no longer publicly available.' %}

diff --git a/templates/email/recording/shared_data_unrecorded_team.html b/templates/email/recording/shared_data_unrecorded_team.html index 5c0f856..6ac1d75 100644 --- a/templates/email/recording/shared_data_unrecorded_team.html +++ b/templates/email/recording/shared_data_unrecorded_team.html @@ -14,6 +14,17 @@
"{{obj_title}}"
+
+ {% trans 'This entry is located in' %} +
    + {% for municipal in municipals_names %} +
  • {{municipal}}
  • + {% empty %} +
+ {% trans 'Unknown - No administrative location recognized' %} +
+ {% endfor %} + {% trans 'This means the data is no longer publicly available.' %}

diff --git a/templates/email/resubmission/resubmission.html b/templates/email/resubmission/resubmission.html index 25848f5..0dcc32c 100644 --- a/templates/email/resubmission/resubmission.html +++ b/templates/email/resubmission/resubmission.html @@ -18,6 +18,16 @@ {% endif %}

+ {% trans 'This entry is located in' %} +
    + {% for municipal in municipals_names %} +
  • {{municipal}}
  • + {% empty %} +
+ {% trans 'Unknown - No administrative location recognized' %} + {% endfor %} + +
{% trans 'Best regards' %}
KSP diff --git a/templates/email/sharing/shared_access_given.html b/templates/email/sharing/shared_access_given.html index 6ab759b..785e602 100644 --- a/templates/email/sharing/shared_access_given.html +++ b/templates/email/sharing/shared_access_given.html @@ -14,6 +14,16 @@
"{{obj_title}}"
+
+ {% trans 'This entry is located in' %} +
    + {% for municipal in municipals_names %} +
  • {{municipal}}
  • + {% empty %} +
+ {% trans 'Unknown - No administrative location recognized' %} + {% endfor %} + {% trans 'This means you can now edit this dataset.' %} {% trans 'The shared dataset appears now by default on your overview for this dataset type.' %}
diff --git a/templates/email/sharing/shared_access_given_team.html b/templates/email/sharing/shared_access_given_team.html index cdf3bb1..0f23bc5 100644 --- a/templates/email/sharing/shared_access_given_team.html +++ b/templates/email/sharing/shared_access_given_team.html @@ -14,6 +14,17 @@
"{{obj_title}}"
+
+ {% trans 'This entry is located in' %} +
+
    + {% for municipal in municipals_names %} +
  • {{municipal}}
  • + {% empty %} +
+ {% trans 'Unknown - No administrative location recognized' %} + {% endfor %} + {% trans 'This means you can now edit this dataset.' %} {% trans 'The shared dataset appears now by default on your overview for this dataset type.' %}
diff --git a/templates/email/sharing/shared_access_removed.html b/templates/email/sharing/shared_access_removed.html index b312111..f1845a3 100644 --- a/templates/email/sharing/shared_access_removed.html +++ b/templates/email/sharing/shared_access_removed.html @@ -14,6 +14,16 @@
"{{obj_title}}"
+
+ {% trans 'This entry is located in' %} +
    + {% for municipal in municipals_names %} +
  • {{municipal}}
  • + {% empty %} +
+ {% trans 'Unknown - No administrative location recognized' %} + {% endfor %} + {% trans 'However, you are still able to view the dataset content.' %} {% trans 'Please use the provided search filter on the dataset`s overview pages to find them.' %}
diff --git a/templates/email/sharing/shared_access_removed_team.html b/templates/email/sharing/shared_access_removed_team.html index 992f00f..ede0520 100644 --- a/templates/email/sharing/shared_access_removed_team.html +++ b/templates/email/sharing/shared_access_removed_team.html @@ -14,6 +14,16 @@
"{{obj_title}}"
+
+ {% trans 'This entry is located in' %} +
    + {% for municipal in municipals_names %} +
  • {{municipal}}
  • + {% empty %} +
+ {% trans 'Unknown - No administrative location recognized' %} + {% endfor %} + {% trans 'However, you are still able to view the dataset content.' %} {% trans 'Please use the provided search filter on the dataset`s overview pages to find them.' %}
diff --git a/user/models/team.py b/user/models/team.py index b4bc26c..0ff18a8 100644 --- a/user/models/team.py +++ b/user/models/team.py @@ -31,12 +31,13 @@ class Team(UuidModel, DeletableObjectMixin): self.deleted = delete_action self.save() - def send_mail_shared_access_given_team(self, obj_identifier, obj_title): + def send_mail_shared_access_given_team(self, obj_identifier, obj_title, municipals_names): """ Sends a mail to the team members in case of given shared access Args: - obj_identifier (): - obj_title (): + obj_identifier (str): The entry identifier + obj_title (str): The entry title + municipals_names (iterable): List of municipals for this entry Returns: @@ -45,14 +46,15 @@ class Team(UuidModel, DeletableObjectMixin): users_to_notify = self.users.filter( notifications__in=[UserNotificationEnum.NOTIFY_ON_SHARED_ACCESS_GAINED.value] ) - mailer.send_mail_shared_access_given_team(obj_identifier, obj_title, self, users_to_notify) + mailer.send_mail_shared_access_given_team(obj_identifier, obj_title, self, users_to_notify, municipals_names) - def send_mail_shared_access_removed(self, obj_identifier, obj_title): + def send_mail_shared_access_removed(self, obj_identifier, obj_title, municipals_names): """ Sends a mail to the team members in case of removed shared access Args: - obj_identifier (): - obj_title (): + obj_identifier (str): The entry identifier + obj_title (str): The entry title + municipals_names (iterable): List of municipals for this entry Returns: @@ -61,14 +63,15 @@ class Team(UuidModel, DeletableObjectMixin): users_to_notify = self.users.filter( notifications__in=[UserNotificationEnum.NOTIFY_ON_SHARED_ACCESS_REMOVED.value] ) - mailer.send_mail_shared_access_removed_team(obj_identifier, obj_title, self, users_to_notify) + mailer.send_mail_shared_access_removed_team(obj_identifier, obj_title, self, users_to_notify, municipals_names) - def send_mail_shared_data_unrecorded(self, obj_identifier, obj_title): + def send_mail_shared_data_unrecorded(self, obj_identifier, obj_title, municipals_names): """ Sends a mail to the team members in case of unrecorded data Args: - obj_identifier (): - obj_title (): + obj_identifier (str): The entry identifier + obj_title (str): The entry title + municipals_names (iterable): List of municipals for this entry Returns: @@ -77,14 +80,15 @@ class Team(UuidModel, DeletableObjectMixin): users_to_notify = self.users.filter( notifications__in=[UserNotificationEnum.NOTIFY_ON_SHARED_DATA_RECORDED.value] ) - mailer.send_mail_shared_data_unrecorded_team(obj_identifier, obj_title, self, users_to_notify) + mailer.send_mail_shared_data_unrecorded_team(obj_identifier, obj_title, self, users_to_notify, municipals_names) - def send_mail_shared_data_recorded(self, obj_identifier, obj_title): + def send_mail_shared_data_recorded(self, obj_identifier, obj_title, municipals_names): """ Sends a mail to the team members in case of unrecorded data Args: - obj_identifier (): - obj_title (): + obj_identifier (str): The entry identifier + obj_title (str): The entry title + municipals_names (iterable): List of municipals for this entry Returns: @@ -93,14 +97,15 @@ class Team(UuidModel, DeletableObjectMixin): users_to_notify = self.users.filter( notifications__in=[UserNotificationEnum.NOTIFY_ON_SHARED_DATA_RECORDED.value] ) - mailer.send_mail_shared_data_recorded_team(obj_identifier, obj_title, self, users_to_notify) + mailer.send_mail_shared_data_recorded_team(obj_identifier, obj_title, self, users_to_notify, municipals_names) - def send_mail_shared_data_checked(self, obj_identifier, obj_title): + def send_mail_shared_data_checked(self, obj_identifier, obj_title, municipals_names): """ Sends a mail to the team members in case of checked data Args: - obj_identifier (): - obj_title (): + obj_identifier (str): The entry identifier + obj_title (str): The entry title + municipals_names (iterable): List of municipals for this entry Returns: @@ -109,7 +114,7 @@ class Team(UuidModel, DeletableObjectMixin): users_to_notify = self.users.filter( notifications__in=[UserNotificationEnum.NOTIFY_ON_SHARED_DATA_CHECKED.value] ) - mailer.send_mail_shared_data_checked_team(obj_identifier, obj_title, self, users_to_notify) + mailer.send_mail_shared_data_checked_team(obj_identifier, obj_title, self, users_to_notify, municipals_names) def send_mail_deduction_changed(self, obj_identifier, obj_title, data_changes): """ Sends a mail to the team members in case of changed deduction values @@ -128,12 +133,13 @@ class Team(UuidModel, DeletableObjectMixin): ) mailer.send_mail_deduction_changed_team(obj_identifier, obj_title, self, data_changes, users_to_notify) - def send_mail_shared_data_deleted(self, obj_identifier, obj_title): + def send_mail_shared_data_deleted(self, obj_identifier, obj_title, municipals_names): """ Sends a mail to the team members in case of deleted data Args: - obj_identifier (): - obj_title (): + obj_identifier (str): The entry identifier + obj_title (str): The entry title + municipals_names (iterable): List of municipals for this entry Returns: @@ -142,7 +148,7 @@ class Team(UuidModel, DeletableObjectMixin): users_to_notify = self.users.filter( notifications__in=[UserNotificationEnum.NOTIFY_ON_SHARED_DATA_DELETED.value] ) - mailer.send_mail_shared_data_deleted_team(obj_identifier, obj_title, self, users_to_notify) + mailer.send_mail_shared_data_deleted_team(obj_identifier, obj_title, self, users_to_notify, municipals_names) def remove_user(self, user): """ Removes a user from the team diff --git a/user/models/user.py b/user/models/user.py index 20d3d50..ad7a3ec 100644 --- a/user/models/user.py +++ b/user/models/user.py @@ -60,12 +60,13 @@ class User(AbstractUser): name=ETS_GROUP ).exists() - def send_mail_shared_access_removed(self, obj_identifier, obj_title): + def send_mail_shared_access_removed(self, obj_identifier, obj_title, municipals_names): """ Sends a mail to the user in case of removed shared access Args: obj_identifier (): obj_title (): + municipals_names (): Returns: @@ -73,13 +74,15 @@ class User(AbstractUser): notification_set = self.is_notification_setting_set(UserNotificationEnum.NOTIFY_ON_SHARED_ACCESS_REMOVED) if notification_set: mailer = Mailer() - mailer.send_mail_shared_access_removed(obj_identifier, obj_title, self) + mailer.send_mail_shared_access_removed(obj_identifier, obj_title, self, municipals_names) - def send_mail_shared_access_given(self, obj_identifier, obj_title): + def send_mail_shared_access_given(self, obj_identifier, obj_title, municipals_names): """ Sends a mail to the user in case of given shared access Args: - obj_identifier (): + obj_identifier (str): The entry identifier + obj_title (str): The entry title + municipals_names (iterable): List of municipals for this entry Returns: @@ -87,13 +90,15 @@ class User(AbstractUser): notification_set = self.is_notification_setting_set(UserNotificationEnum.NOTIFY_ON_SHARED_ACCESS_GAINED) if notification_set: mailer = Mailer() - mailer.send_mail_shared_access_given(obj_identifier, obj_title, self) + mailer.send_mail_shared_access_given(obj_identifier, obj_title, self, municipals_names) - def send_mail_shared_data_recorded(self, obj_identifier, obj_title): + def send_mail_shared_data_recorded(self, obj_identifier, obj_title, municipals_names): """ Sends a mail to the user in case of shared data has been recorded Args: - obj_identifier (): + obj_identifier (str): The entry identifier + obj_title (str): The entry title + municipals_names (iterable): List of municipals for this entry Returns: @@ -101,13 +106,15 @@ class User(AbstractUser): notification_set = self.is_notification_setting_set(UserNotificationEnum.NOTIFY_ON_SHARED_DATA_RECORDED) if notification_set: mailer = Mailer() - mailer.send_mail_shared_data_recorded(obj_identifier, obj_title, self) + mailer.send_mail_shared_data_recorded(obj_identifier, obj_title, self, municipals_names) - def send_mail_shared_data_unrecorded(self, obj_identifier, obj_title): + def send_mail_shared_data_unrecorded(self, obj_identifier, obj_title, municipals_names): """ Sends a mail to the user in case of shared data has been unrecorded Args: - obj_identifier (): + obj_identifier (str): The entry identifier + obj_title (str): The entry title + municipals_names (iterable): List of municipals for this entry Returns: @@ -115,13 +122,15 @@ class User(AbstractUser): notification_set = self.is_notification_setting_set(UserNotificationEnum.NOTIFY_ON_SHARED_DATA_RECORDED) if notification_set: mailer = Mailer() - mailer.send_mail_shared_data_unrecorded(obj_identifier, obj_title, self) + mailer.send_mail_shared_data_unrecorded(obj_identifier, obj_title, self, municipals_names) - def send_mail_shared_data_deleted(self, obj_identifier, obj_title): + def send_mail_shared_data_deleted(self, obj_identifier, obj_title, municipals_names): """ Sends a mail to the user in case of shared data has been deleted Args: - obj_identifier (): + obj_identifier (str): The entry identifier + obj_title (str): The entry title + municipals_names (iterable): List of municipals for this entry Returns: @@ -129,13 +138,15 @@ class User(AbstractUser): notification_set = self.is_notification_setting_set(UserNotificationEnum.NOTIFY_ON_SHARED_DATA_DELETED) if notification_set: mailer = Mailer() - mailer.send_mail_shared_data_deleted(obj_identifier, obj_title, self) + mailer.send_mail_shared_data_deleted(obj_identifier, obj_title, self, municipals_names) - def send_mail_shared_data_checked(self, obj_identifier, obj_title): + def send_mail_shared_data_checked(self, obj_identifier, obj_title, municipals_names): """ Sends a mail to the user in case of shared data has been deleted Args: - obj_identifier (): + obj_identifier (str): The entry identifier + obj_title (str): The entry title + municipals_names (iterable): List of municipals for this entry Returns: @@ -143,7 +154,7 @@ class User(AbstractUser): notification_set = self.is_notification_setting_set(UserNotificationEnum.NOTIFY_ON_SHARED_DATA_CHECKED) if notification_set: mailer = Mailer() - mailer.send_mail_shared_data_checked(obj_identifier, obj_title, self) + mailer.send_mail_shared_data_checked(obj_identifier, obj_title, self, municipals_names) def send_mail_deduction_changed(self, obj_identifier, obj_title, data_changes): """ Sends a mail to the user in case of a changed deduction