diff --git a/compensation/forms/forms.py b/compensation/forms/forms.py index dbd3c6c..0970daa 100644 --- a/compensation/forms/forms.py +++ b/compensation/forms/forms.py @@ -6,7 +6,7 @@ Created on: 04.12.20 """ from dal import autocomplete -from django.contrib.auth.models import User +from user.models import User from django.db import transaction from django.urls import reverse_lazy, reverse from django.utils.translation import gettext_lazy as _ diff --git a/compensation/models/compensation.py b/compensation/models/compensation.py index 65a62b6..b68ad10 100644 --- a/compensation/models/compensation.py +++ b/compensation/models/compensation.py @@ -8,7 +8,7 @@ Created on: 16.11.21 import shutil from django.contrib import messages -from django.contrib.auth.models import User +from user.models import User from django.db import models, transaction from django.db.models import QuerySet, Sum from django.http import HttpRequest diff --git a/compensation/models/eco_account.py b/compensation/models/eco_account.py index dad7bff..7d339b4 100644 --- a/compensation/models/eco_account.py +++ b/compensation/models/eco_account.py @@ -7,7 +7,7 @@ Created on: 16.11.21 """ import shutil -from django.contrib.auth.models import User +from user.models import User from django.core.exceptions import ValidationError from django.core.validators import MinValueValidator from django.db import models, transaction diff --git a/compensation/tables.py b/compensation/tables.py index 6e6a190..9daf2b2 100644 --- a/compensation/tables.py +++ b/compensation/tables.py @@ -5,7 +5,7 @@ Contact: michel.peltriaux@sgdnord.rlp.de Created on: 01.12.20 """ -from django.contrib.auth.models import User +from user.models import User from django.http import HttpRequest from django.template.loader import render_to_string from django.urls import reverse diff --git a/compensation/utils/quality.py b/compensation/utils/quality.py index b7f8daa..b622fcd 100644 --- a/compensation/utils/quality.py +++ b/compensation/utils/quality.py @@ -58,20 +58,8 @@ class EcoAccountQualityChecker(CompensationQualityChecker): self._check_deductable_surface() self._check_responsible_data() self._check_legal_data() - self._check_record_state() super().run_check() - def _check_record_state(self): - """ Checks the data quality for recorded state - - Returns: - - """ - if self.obj.recorded is None: - self.messages.append( - _("Not recorded") - ) - def _check_legal_data(self): """ Checks the data quality for Legal diff --git a/ema/forms.py b/ema/forms.py index cb7f0cc..5dc3bcf 100644 --- a/ema/forms.py +++ b/ema/forms.py @@ -7,7 +7,7 @@ Created on: 06.10.21 """ from dal import autocomplete from django import forms -from django.contrib.auth.models import User +from user.models import User from django.db import transaction from django.urls import reverse, reverse_lazy from django.utils.translation import gettext_lazy as _ diff --git a/intervention/forms/forms.py b/intervention/forms/forms.py index 5340dd6..6f09815 100644 --- a/intervention/forms/forms.py +++ b/intervention/forms/forms.py @@ -7,7 +7,7 @@ Created on: 02.12.20 """ from dal import autocomplete from django import forms -from django.contrib.auth.models import User +from user.models import User from django.db import transaction from django.urls import reverse, reverse_lazy from django.utils.translation import gettext_lazy as _ diff --git a/intervention/forms/modalForms.py b/intervention/forms/modalForms.py index aea9f2c..063a912 100644 --- a/intervention/forms/modalForms.py +++ b/intervention/forms/modalForms.py @@ -6,7 +6,7 @@ Created on: 27.09.21 """ from dal import autocomplete -from django.contrib.auth.models import User +from user.models import User from django.db import transaction from django import forms from django.urls import reverse diff --git a/intervention/models/intervention.py b/intervention/models/intervention.py index 737dd40..6f72123 100644 --- a/intervention/models/intervention.py +++ b/intervention/models/intervention.py @@ -8,7 +8,7 @@ Created on: 15.11.21 import shutil from django.contrib import messages -from django.contrib.auth.models import User +from user.models import User from django.db import models, transaction from django.db.models import QuerySet from django.http import HttpRequest diff --git a/konova/autocompletes.py b/konova/autocompletes.py index f47117c..bee8dad 100644 --- a/konova/autocompletes.py +++ b/konova/autocompletes.py @@ -6,7 +6,7 @@ Created on: 07.12.20 """ from dal_select2.views import Select2QuerySetView, Select2GroupQuerySetView -from django.contrib.auth.models import User +from user.models import User from django.db.models import Q from codelist.models import KonovaCode diff --git a/konova/forms.py b/konova/forms.py index 4ad309e..aae83e6 100644 --- a/konova/forms.py +++ b/konova/forms.py @@ -12,7 +12,7 @@ from bootstrap_modal_forms.forms import BSModalForm from bootstrap_modal_forms.utils import is_ajax from django import forms from django.contrib import messages -from django.contrib.auth.models import User +from user.models import User from django.contrib.gis.forms import OSMWidget, MultiPolygonField from django.contrib.gis.geos import MultiPolygon from django.db import transaction diff --git a/konova/management/commands/setup.py b/konova/management/commands/setup.py index f02a8e3..6c52ba9 100644 --- a/konova/management/commands/setup.py +++ b/konova/management/commands/setup.py @@ -7,7 +7,8 @@ Created on: 15.12.20 """ from getpass import getpass -from django.contrib.auth.models import User, Group +from user.models import User +from django.contrib.auth.models import Group from django.core.management import BaseCommand, call_command from django.db import transaction diff --git a/konova/management/commands/setup_data.py b/konova/management/commands/setup_data.py index 85e6490..4a5683c 100644 --- a/konova/management/commands/setup_data.py +++ b/konova/management/commands/setup_data.py @@ -23,10 +23,9 @@ GROUPS_DATA = [ # Must match with UserNotificationEnum USER_NOTIFICATIONS_NAMES = { - "NOTIFY_ON_NEW_RELATED_DATA": _("On new related data"), - "NOTIFY_ON_SHARE_LINK_DISABLED": _("On disabled share link"), + "NOTIFY_ON_SHARED_ACCESS_GAINED": _("On shared access gained"), "NOTIFY_ON_SHARED_ACCESS_REMOVED": _("On shared access removed"), "NOTIFY_ON_SHARED_DATA_RECORDED": _("On shared data recorded"), "NOTIFY_ON_SHARED_DATA_DELETED": _("On shared data deleted"), - "NOTIFY_ON_REGISTERED_DATA_EDITED": _("On registered data edited"), + "NOTIFY_ON_SHARED_DATA_CHECKED": _("On shared data checked"), } \ No newline at end of file diff --git a/konova/models/object.py b/konova/models/object.py index 49c1f4e..a27398d 100644 --- a/konova/models/object.py +++ b/konova/models/object.py @@ -10,7 +10,11 @@ import uuid from abc import abstractmethod from django.contrib import messages -from django.contrib.auth.models import User + +from konova.tasks import celery_send_mail_shared_access_removed, celery_send_mail_shared_access_given, \ + celery_send_mail_shared_data_recorded, celery_send_mail_shared_data_unrecorded, \ + celery_send_mail_shared_data_deleted, celery_send_mail_shared_data_checked +from user.models import User from django.core.exceptions import ObjectDoesNotExist from django.http import HttpRequest from django.utils.timezone import now @@ -118,6 +122,12 @@ class BaseObject(BaseResource): action = UserActionLogEntry.get_deleted_action(user) self.deleted = action self.log.add(action) + + # Send mail + shared_users = self.users.all().values_list("id", flat=True) + for user_id in shared_users: + celery_send_mail_shared_data_deleted.delay(self.identifier, user_id) + self.save() def add_log_entry(self, action: UserAction, user: User, comment: str): @@ -216,6 +226,11 @@ class RecordableObjectMixin(models.Model): self.recorded = None self.save() self.log.add(action) + + shared_users = self.users.all().values_list("id", flat=True) + for user_id in shared_users: + celery_send_mail_shared_data_unrecorded(self.identifier, user_id) + return action def set_recorded(self, user: User): @@ -233,6 +248,11 @@ class RecordableObjectMixin(models.Model): self.recorded = action self.save() self.log.add(action) + + shared_users = self.users.all().values_list("id", flat=True) + for user_id in shared_users: + celery_send_mail_shared_data_recorded(self.identifier, user_id) + return action def mark_as_edited(self, performing_user: User, request: HttpRequest = None, edit_comment: str = None): @@ -305,6 +325,12 @@ class CheckableObjectMixin(models.Model): action = UserActionLogEntry.get_checked_action(user) self.checked = action self.save() + + # Send mail + shared_users = self.users.all().values_list("id", flat=True) + for user_id in shared_users: + celery_send_mail_shared_data_checked.delay(self.identifier, user_id) + self.log.add(action) return action @@ -411,6 +437,17 @@ class ShareableObjectMixin(models.Model): users = User.objects.filter( id__in=accessing_users ) + removed_users = self.users.all().exclude( + id__in=accessing_users + ).values("id") + + # Send mails + for user in removed_users: + celery_send_mail_shared_access_removed.delay(self.identifier, user["id"]) + for user in new_accessing_users: + celery_send_mail_shared_access_given.delay(self.identifier, user) + + # Set new shared users self.share_with_list(users) diff --git a/konova/sso/sso.py b/konova/sso/sso.py index 69cd2b3..f33376f 100644 --- a/konova/sso/sso.py +++ b/konova/sso/sso.py @@ -5,9 +5,10 @@ Contact: michel.peltriaux@sgdnord.rlp.de Created on: 17.08.21 """ -from django.contrib.auth.models import User from simple_sso.sso_client.client import Client +from user.models import User + class KonovaSSOClient(Client): """ Konova specialized derivate of general sso.Client. diff --git a/konova/sub_settings/django_settings.py b/konova/sub_settings/django_settings.py index df875a8..bc1a751 100644 --- a/konova/sub_settings/django_settings.py +++ b/konova/sub_settings/django_settings.py @@ -129,7 +129,7 @@ DATABASES = { # Password validation # https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators - +AUTH_USER_MODEL = "user.User" AUTH_PASSWORD_VALIDATORS = [ { 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', @@ -204,9 +204,15 @@ DEBUG_TOOLBAR_CONFIG = { } # EMAIL (see https://docs.djangoproject.com/en/dev/topics/email/) -DEFAULT_FROM_EMAIL = "bot@arneo.de" # The default email address for the 'from' element + +# CHANGE_ME !!! ONLY FOR DEVELOPMENT !!! +EMAIL_BACKEND = 'django.core.mail.backends.filebased.EmailBackend' +EMAIL_FILE_PATH = '/tmp/app-messages' # change this to a proper location + +DEFAULT_FROM_EMAIL = "service@ksp.de" # The default email address for the 'from' element EMAIL_HOST = "localhost" -EMAIL_PORT = "1025" +EMAIL_REPLY_TO = "ksp-servicestelle@sgdnord.rlp.de" +EMAIL_PORT = "25" #EMAIL_HOST_USER = "" #EMAIL_HOST_PASSWORD = "" EMAIL_USE_TLS = False diff --git a/konova/tasks.py b/konova/tasks.py index b0108a4..a463374 100644 --- a/konova/tasks.py +++ b/konova/tasks.py @@ -1,14 +1,60 @@ +from time import sleep + from celery import shared_task from django.core.exceptions import ObjectDoesNotExist -from konova.models import Geometry @shared_task -def celery_update_parcels(geometry_id: str): +def celery_update_parcels(geometry_id: str, recheck: bool = True): + from konova.models import Geometry try: geom = Geometry.objects.get(id=geometry_id) geom.parcels.clear() geom.update_parcels() except ObjectDoesNotExist: - return + if recheck: + sleep(5) + celery_update_parcels(geometry_id, False) + + +@shared_task +def celery_send_mail_shared_access_removed(obj_identifier, user_id): + from user.models import User + user = User.objects.get(id=user_id) + user.send_mail_shared_access_removed(obj_identifier) + + +@shared_task +def celery_send_mail_shared_access_given(obj_identifier, user_id): + from user.models import User + user = User.objects.get(id=user_id) + user.send_mail_shared_access_given(obj_identifier) + + +@shared_task +def celery_send_mail_shared_data_recorded(obj_identifier, user_id): + from user.models import User + user = User.objects.get(id=user_id) + user.send_mail_shared_data_recorded(obj_identifier) + + +@shared_task +def celery_send_mail_shared_data_unrecorded(obj_identifier, user_id): + from user.models import User + user = User.objects.get(id=user_id) + user.send_mail_shared_data_unrecorded(obj_identifier) + + +@shared_task +def celery_send_mail_shared_data_deleted(obj_identifier, user_id): + from user.models import User + user = User.objects.get(id=user_id) + user.send_mail_shared_data_deleted(obj_identifier) + + +@shared_task +def celery_send_mail_shared_data_checked(obj_identifier, user_id): + from user.models import User + user = User.objects.get(id=user_id) + user.send_mail_shared_data_checked(obj_identifier) diff --git a/konova/tests/test_views.py b/konova/tests/test_views.py index dad4429..1e0ae7f 100644 --- a/konova/tests/test_views.py +++ b/konova/tests/test_views.py @@ -7,7 +7,8 @@ Created on: 26.10.21 """ import datetime -from django.contrib.auth.models import User, Group +from user.models import User +from django.contrib.auth.models import Group from django.contrib.gis.geos import MultiPolygon, Polygon from django.core.exceptions import ObjectDoesNotExist from django.test import TestCase, Client diff --git a/konova/utils/mailer.py b/konova/utils/mailer.py index 0dc32c6..9c273ff 100644 --- a/konova/utils/mailer.py +++ b/konova/utils/mailer.py @@ -8,8 +8,10 @@ Created on: 09.11.20 import logging from django.core.mail import send_mail +from django.template.loader import render_to_string +from django.utils.translation import gettext_lazy as _ -from konova.sub_settings.django_settings import DEFAULT_FROM_EMAIL +from konova.sub_settings.django_settings import DEFAULT_FROM_EMAIL, EMAIL_REPLY_TO logger = logging.getLogger(__name__) @@ -26,27 +28,156 @@ class Mailer: auth_user = None auth_password = None - def __init__(self, to_mail: list, from_mail: str = DEFAULT_FROM_EMAIL, auth_user: str = None, auth_password: str = None, fail_silently: bool = False): - # Make sure given to_mail parameter is a list - if isinstance(to_mail, str): - to_mail = [to_mail] - + def __init__(self, from_mail: str = DEFAULT_FROM_EMAIL, auth_user: str = None, auth_password: str = None, fail_silently: bool = False): self.from_mail = from_mail - self.to_mail = to_mail self.fail_silently = fail_silently self.auth_user = auth_user self.auth_password = auth_password - def send(self, subject: str, msg: str): + def send(self, recipient_list: list, subject: str, msg: str): """ Sends a mail with subject and message """ return send_mail( subject=subject, - message=msg, + message=None, + html_message=msg, from_email=self.from_mail, - recipient_list=self.to_mail, + recipient_list=recipient_list, fail_silently=self.fail_silently, auth_user=self.auth_user, auth_password=self.auth_password - ) \ No newline at end of file + ) + + def send_mail_shared_access_removed(self, obj_identifier, user): + """ Send a mail if user has no access to the object anymore + + Args: + obj_identifier (str): The object identifier + + Returns: + + """ + context = { + "user": user, + "obj_identifier": obj_identifier, + "EMAIL_REPLY_TO": EMAIL_REPLY_TO, + } + msg = render_to_string("email/sharing/shared_access_removed.html", context) + user_mail_address = [user.email] + self.send( + user_mail_address, + _("{} - Shared access removed").format(obj_identifier), + msg + ) + + def send_mail_shared_access_given(self, obj_identifier, user): + """ Send a mail if user just got access to the object + + Args: + obj_identifier (str): The object identifier + + Returns: + + """ + context = { + "user": user, + "obj_identifier": obj_identifier, + "EMAIL_REPLY_TO": EMAIL_REPLY_TO, + } + msg = render_to_string("email/sharing/shared_access_given.html", context) + user_mail_address = [user.email] + self.send( + user_mail_address, + _("{} - Shared access given").format(obj_identifier), + msg + ) + + def send_mail_shared_data_recorded(self, obj_identifier, user): + """ Send a mail if the user's shared data has just been unrecorded + + Args: + obj_identifier (str): The object identifier + + Returns: + + """ + context = { + "user": user, + "obj_identifier": obj_identifier, + "EMAIL_REPLY_TO": EMAIL_REPLY_TO, + } + msg = render_to_string("email/recording/shared_data_recorded.html", context) + user_mail_address = [user.email] + self.send( + user_mail_address, + _("{} - Shared data recorded").format(obj_identifier), + msg + ) + + def send_mail_shared_data_unrecorded(self, obj_identifier, user): + """ Send a mail if the user's shared data has just been unrecorded + + Args: + obj_identifier (str): The object identifier + + Returns: + + """ + context = { + "user": user, + "obj_identifier": obj_identifier, + "EMAIL_REPLY_TO": EMAIL_REPLY_TO, + } + msg = render_to_string("email/recording/shared_data_unrecorded.html", context) + user_mail_address = [user.email] + self.send( + user_mail_address, + _("{} - Shared data unrecorded").format(obj_identifier), + msg + ) + + def send_mail_shared_data_deleted(self, obj_identifier, user): + """ Send a mail if shared data has just been deleted + + Args: + obj_identifier (str): The object identifier + + Returns: + + """ + context = { + "user": user, + "obj_identifier": obj_identifier, + "EMAIL_REPLY_TO": EMAIL_REPLY_TO, + } + msg = render_to_string("email/deleting/shared_data_deleted.html", context) + user_mail_address = [user.email] + self.send( + user_mail_address, + _("{} - Shared data deleted").format(obj_identifier), + msg + ) + + def send_mail_shared_data_checked(self, obj_identifier, user): + """ Send a mail if shared data just has been checked + + Args: + obj_identifier (str): The object identifier + + Returns: + + """ + context = { + "user": user, + "obj_identifier": obj_identifier, + "EMAIL_REPLY_TO": EMAIL_REPLY_TO, + } + msg = render_to_string("email/checking/shared_data_checked.html", context) + user_mail_address = [user.email] + self.send( + user_mail_address, + _("{} - Shared data checked").format(obj_identifier), + msg + ) + diff --git a/konova/utils/messenger.py b/konova/utils/messenger.py index 8169d5e..5be4dc1 100644 --- a/konova/utils/messenger.py +++ b/konova/utils/messenger.py @@ -8,7 +8,7 @@ Created on: 17.08.21 from collections import Iterable import requests -from django.contrib.auth.models import User +from user.models import User from django.utils.translation import gettext_lazy as _ from konova.settings import SSO_SERVER_BASE, SSO_PUBLIC_KEY, PROXIES diff --git a/konova/utils/user_checks.py b/konova/utils/user_checks.py index a01dadb..b4f6527 100644 --- a/konova/utils/user_checks.py +++ b/konova/utils/user_checks.py @@ -5,7 +5,7 @@ Contact: michel.peltriaux@sgdnord.rlp.de Created on: 02.07.21 """ -from django.contrib.auth.models import User +from user.models import User from konova.settings import ETS_GROUP, ZB_GROUP diff --git a/locale/de/LC_MESSAGES/django.mo b/locale/de/LC_MESSAGES/django.mo index 1246234..2790b18 100644 Binary files a/locale/de/LC_MESSAGES/django.mo and b/locale/de/LC_MESSAGES/django.mo differ diff --git a/locale/de/LC_MESSAGES/django.po b/locale/de/LC_MESSAGES/django.po index cb6b2a8..54fd22a 100644 --- a/locale/de/LC_MESSAGES/django.po +++ b/locale/de/LC_MESSAGES/django.po @@ -3,26 +3,30 @@ # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # -#: compensation/filters.py:91 compensation/forms/modalForms.py:34 +#: compensation/filters.py:122 compensation/forms/modalForms.py:34 #: compensation/forms/modalForms.py:45 compensation/forms/modalForms.py:61 #: compensation/forms/modalForms.py:238 compensation/forms/modalForms.py:316 #: intervention/forms/forms.py:52 intervention/forms/forms.py:154 #: intervention/forms/forms.py:166 intervention/forms/modalForms.py:125 #: intervention/forms/modalForms.py:138 intervention/forms/modalForms.py:151 -#: konova/filters.py:63 konova/filters.py:64 konova/filters.py:91 -#: konova/filters.py:92 konova/filters.py:104 konova/filters.py:105 -#: konova/filters.py:117 konova/filters.py:118 konova/filters.py:130 -#: konova/filters.py:131 konova/filters.py:144 konova/filters.py:145 -#: konova/filters.py:280 konova/filters.py:324 konova/forms.py:140 -#: konova/forms.py:241 konova/forms.py:312 konova/forms.py:339 -#: konova/forms.py:349 konova/forms.py:362 konova/forms.py:374 -#: konova/forms.py:392 user/forms.py:38 +#: konova/filters/mixins.py:53 konova/filters/mixins.py:54 +#: konova/filters/mixins.py:81 konova/filters/mixins.py:82 +#: konova/filters/mixins.py:94 konova/filters/mixins.py:95 +#: konova/filters/mixins.py:107 konova/filters/mixins.py:108 +#: konova/filters/mixins.py:120 konova/filters/mixins.py:121 +#: konova/filters/mixins.py:134 konova/filters/mixins.py:135 +#: konova/filters/mixins.py:270 konova/filters/mixins.py:315 +#: konova/filters/mixins.py:353 konova/filters/mixins.py:354 +#: konova/filters/mixins.py:385 konova/filters/mixins.py:386 +#: konova/forms.py:140 konova/forms.py:241 konova/forms.py:312 +#: konova/forms.py:339 konova/forms.py:349 konova/forms.py:362 +#: konova/forms.py:374 konova/forms.py:392 user/forms.py:38 #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-01-11 17:07+0100\n" +"POT-Creation-Date: 2022-01-12 15:43+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -43,12 +47,12 @@ msgstr "Bis" #: analysis/forms.py:47 compensation/forms/forms.py:77 #: compensation/templates/compensation/detail/eco_account/view.html:58 #: compensation/templates/compensation/report/eco_account/report.html:16 -#: compensation/utils/quality.py:112 ema/templates/ema/detail/view.html:49 +#: compensation/utils/quality.py:100 ema/templates/ema/detail/view.html:49 #: ema/templates/ema/report/report.html:16 ema/utils/quality.py:26 #: intervention/forms/forms.py:100 #: intervention/templates/intervention/detail/view.html:56 #: intervention/templates/intervention/report/report.html:37 -#: intervention/utils/quality.py:49 +#: intervention/utils/quality.py:49 konova/filters/mixins.py:395 msgid "Conservation office" msgstr "Eintragungsstelle" @@ -136,7 +140,7 @@ msgstr "Zuständigkeitsbereich" #: compensation/templates/compensation/detail/compensation/view.html:63 #: intervention/tables.py:33 #: intervention/templates/intervention/detail/view.html:68 -#: user/models/user_action.py:19 +#: user/models/user_action.py:18 msgid "Checked" msgstr "Geprüft" @@ -155,7 +159,7 @@ msgstr "Geprüft" #: ema/tables.py:38 ema/templates/ema/detail/view.html:35 #: intervention/tables.py:39 #: intervention/templates/intervention/detail/view.html:82 -#: user/models/user_action.py:20 +#: user/models/user_action.py:19 msgid "Recorded" msgstr "Verzeichnet" @@ -301,7 +305,7 @@ msgstr "Altfälle" msgid "Before" msgstr "Vor" -#: compensation/filters.py:90 +#: compensation/filters.py:121 msgid "Show only unrecorded" msgstr "Nur unverzeichnete anzeigen" @@ -370,7 +374,7 @@ msgstr "Zusätzlicher Kommentar" #: compensation/forms/forms.py:93 #: compensation/templates/compensation/detail/eco_account/view.html:62 #: compensation/templates/compensation/report/eco_account/report.html:20 -#: compensation/utils/quality.py:114 ema/templates/ema/detail/view.html:53 +#: compensation/utils/quality.py:102 ema/templates/ema/detail/view.html:53 #: ema/templates/ema/report/report.html:20 ema/utils/quality.py:28 #: intervention/forms/forms.py:128 #: intervention/templates/intervention/detail/view.html:60 @@ -430,7 +434,7 @@ msgstr "Neue Kompensation" msgid "Edit compensation" msgstr "Bearbeite Kompensation" -#: compensation/forms/forms.py:302 compensation/utils/quality.py:96 +#: compensation/forms/forms.py:302 compensation/utils/quality.py:84 msgid "Available Surface" msgstr "Verfügbare Fläche" @@ -440,7 +444,7 @@ msgstr "Die für Abbuchungen zur Verfügung stehende Menge" #: compensation/forms/forms.py:314 #: compensation/templates/compensation/detail/eco_account/view.html:66 -#: compensation/utils/quality.py:84 +#: compensation/utils/quality.py:72 msgid "Agreement date" msgstr "Vereinbarungsdatum" @@ -958,7 +962,7 @@ msgstr "Eingriffskennung" #: compensation/templates/compensation/detail/eco_account/includes/deductions.html:37 #: intervention/templates/intervention/detail/includes/deductions.html:34 -#: user/models/user_action.py:22 +#: user/models/user_action.py:21 msgid "Created" msgstr "Erstellt" @@ -1036,21 +1040,17 @@ msgstr "-" msgid "States unequal" msgstr "Ungleiche Zustandsflächenmengen" -#: compensation/utils/quality.py:72 -msgid "Not recorded" -msgstr "Noch nicht verzeichnet" - -#: compensation/utils/quality.py:86 intervention/utils/quality.py:84 +#: compensation/utils/quality.py:74 intervention/utils/quality.py:84 msgid "Legal data" msgstr "Rechtliche Daten" -#: compensation/utils/quality.py:100 +#: compensation/utils/quality.py:88 msgid "Deductable surface can not be larger than state surface" msgstr "" "Die abbuchbare Fläche darf die Gesamtfläche der Zielzustände nicht " "überschreiten" -#: compensation/utils/quality.py:116 ema/utils/quality.py:30 +#: compensation/utils/quality.py:104 ema/utils/quality.py:30 #: intervention/utils/quality.py:55 msgid "Responsible data" msgstr "Daten zu den verantwortlichen Stellen" @@ -1218,7 +1218,7 @@ msgstr "Mehrfachauswahl möglich" #: intervention/forms/forms.py:84 #: intervention/templates/intervention/detail/view.html:48 #: intervention/templates/intervention/report/report.html:29 -#: intervention/utils/quality.py:46 +#: intervention/utils/quality.py:46 konova/filters/mixins.py:363 msgid "Registration office" msgstr "Zulassungsbehörde" @@ -1508,62 +1508,73 @@ msgstr "" "somit nichts eingeben, bearbeiten oder sonstige Aktionen ausführen. " "Kontaktieren Sie bitte einen Administrator. +++" -#: konova/filters.py:67 +#: konova/filters/mixins.py:57 msgid "File number" msgstr "Aktenzeichen" -#: konova/filters.py:68 +#: konova/filters/mixins.py:58 msgid "Search for file number" msgstr "Nach Aktenzeichen suchen" -#: konova/filters.py:95 +#: konova/filters/mixins.py:85 msgid "District" msgstr "Kreis" -#: konova/filters.py:96 +#: konova/filters/mixins.py:86 msgid "Search for district" msgstr "Nach Kreis suchen" -#: konova/filters.py:108 +#: konova/filters/mixins.py:98 msgid "Parcel gmrkng" msgstr "Gemarkung" -#: konova/filters.py:109 +#: konova/filters/mixins.py:99 msgid "Search for parcel gmrkng" msgstr "Nach Gemarkung suchen" -#: konova/filters.py:121 konova/templates/konova/includes/parcels.html:18 +#: konova/filters/mixins.py:111 +#: konova/templates/konova/includes/parcels.html:18 msgid "Parcel" msgstr "Flur" -#: konova/filters.py:122 +#: konova/filters/mixins.py:112 msgid "Search for parcel" msgstr "Nach Flur suchen" -#: konova/filters.py:134 konova/templates/konova/includes/parcels.html:19 +#: konova/filters/mixins.py:124 +#: konova/templates/konova/includes/parcels.html:19 msgid "Parcel counter" msgstr "Flurstückzähler" -#: konova/filters.py:135 +#: konova/filters/mixins.py:125 msgid "Search for parcel counter" msgstr "Nach Flurstückzähler suchen" -#: konova/filters.py:148 konova/templates/konova/includes/parcels.html:20 +#: konova/filters/mixins.py:138 +#: konova/templates/konova/includes/parcels.html:20 msgid "Parcel number" msgstr "Flurstücknenner" -#: konova/filters.py:149 +#: konova/filters/mixins.py:139 msgid "Search for parcel number" msgstr "Nach Flurstücknenner suchen" -#: konova/filters.py:279 +#: konova/filters/mixins.py:269 msgid "Show unshared" msgstr "Nicht freigegebene anzeigen" -#: konova/filters.py:323 +#: konova/filters/mixins.py:314 msgid "Show recorded" msgstr "Verzeichnete anzeigen" +#: konova/filters/mixins.py:364 +msgid "Search for registration office" +msgstr "Nach Zulassungsbehörde suchen" + +#: konova/filters/mixins.py:396 +msgid "Search for conservation office" +msgstr "Nch Eintragungsstelle suchen" + #: konova/forms.py:37 templates/form/collapsable/form.html:62 msgid "Save" msgstr "Speichern" @@ -1644,28 +1655,24 @@ msgstr "" "Ich, {} {}, bestätige, dass diese Daten wieder entzeichnet werden müssen." #: konova/management/commands/setup_data.py:26 -msgid "On new related data" -msgstr "Wenn neue Daten für mich angelegt werden" +msgid "On shared access gained" +msgstr "Wenn mir eine Freigabe zu Daten erteilt wird" #: konova/management/commands/setup_data.py:27 -msgid "On disabled share link" -msgstr "Wenn ein Freigabelink deaktiviert wird" - -#: konova/management/commands/setup_data.py:28 msgid "On shared access removed" msgstr "Wenn mir eine Freigabe zu Daten entzogen wird" -#: konova/management/commands/setup_data.py:29 +#: konova/management/commands/setup_data.py:28 msgid "On shared data recorded" msgstr "Wenn meine freigegebenen Daten verzeichnet wurden" -#: konova/management/commands/setup_data.py:30 +#: konova/management/commands/setup_data.py:29 msgid "On shared data deleted" msgstr "Wenn meine freigegebenen Daten gelöscht wurden" -#: konova/management/commands/setup_data.py:31 -msgid "On registered data edited" -msgstr "Wenn meine freigegebenen Daten bearbeitet wurden" +#: konova/management/commands/setup_data.py:30 +msgid "On shared data checked" +msgstr "Wenn meine freigegebenen Daten geprüft wurden" #: konova/models/deadline.py:18 msgid "Finished" @@ -1746,6 +1753,30 @@ msgstr "In Zwischenablage kopiert" msgid "Document '{}' deleted" msgstr "Dokument '{}' gelöscht" +#: konova/utils/mailer.py:70 +msgid "{} - Shared access removed" +msgstr "{} - Zugriff entzogen" + +#: konova/utils/mailer.py:92 +msgid "{} - Shared access given" +msgstr "{} - Zugriff freigegeben" + +#: konova/utils/mailer.py:114 +msgid "{} - Shared data recorded" +msgstr "{} - Freigegebene Daten verzeichnet" + +#: konova/utils/mailer.py:136 +msgid "{} - Shared data unrecorded" +msgstr "{} - Freigegebene Daten entzeichnet" + +#: konova/utils/mailer.py:158 +msgid "{} - Shared data deleted" +msgstr "{} - Freigegebene Daten gelöscht" + +#: konova/utils/mailer.py:180 +msgid "{} - Shared data checked" +msgstr "{} - Freigegebene Daten geprüft" + #: konova/utils/message_templates.py:11 msgid "There was an error on this form." msgstr "Es gab einen Fehler im Formular." @@ -1860,6 +1891,157 @@ msgstr "Alle" msgid "News" msgstr "Neuigkeiten" +#: templates/email/checking/shared_data_checked.html:4 +msgid "Shared data checked" +msgstr "Freigegebene Daten geprüft" + +#: templates/email/checking/shared_data_checked.html:8 +#: templates/email/deleting/shared_data_deleted.html:8 +#: templates/email/recording/shared_data_recorded.html:8 +#: templates/email/recording/shared_data_unrecorded.html:8 +#: templates/email/sharing/shared_access_given.html:8 +#: templates/email/sharing/shared_access_removed.html:8 +msgid "Hello " +msgstr "Hallo " + +#: templates/email/checking/shared_data_checked.html:10 +msgid "the following dataset has just been checked" +msgstr "der folgende Datensatz wurde soeben geprüft " + +#: templates/email/checking/shared_data_checked.html:14 +msgid "" +"This means, the responsible registration office just confirmed the " +"correctness of this dataset." +msgstr "" +"Das bedeutet, dass die zuständige Zulassungsbehörde die Korrektheit des Datensatzes " +"soeben bestätigt hat." + +#: templates/email/checking/shared_data_checked.html:17 +#: templates/email/deleting/shared_data_deleted.html:17 +#: templates/email/recording/shared_data_recorded.html:17 +#: templates/email/recording/shared_data_unrecorded.html:17 +#: templates/email/sharing/shared_access_given.html:18 +#: templates/email/sharing/shared_access_removed.html:18 +msgid "Best regards" +msgstr "Beste Grüße" + +#: templates/email/deleting/shared_data_deleted.html:4 +msgid "Shared data deleted" +msgstr "Freigegebene Daten gelöscht" + +#: templates/email/deleting/shared_data_deleted.html:10 +msgid "the following dataset has just been deleted" +msgstr "der folgende Datensatz wurde soeben gelöscht " + +#: templates/email/deleting/shared_data_deleted.html:14 +msgid "" +"If this should not have been happened, please contact us. See the signature " +"for details." +msgstr "" +"Falls das nicht hätte passieren dürfen, kontaktieren Sie uns bitte. In der E-" +"mail Signatur finden Sie weitere Kontaktinformationen." + +#: templates/email/recording/shared_data_recorded.html:4 +msgid "Shared data recorded" +msgstr "Freigegebene Daten verzeichnet" + +#: templates/email/recording/shared_data_recorded.html:10 +msgid "the following dataset has just been recorded" +msgstr "der folgende Datensatz wurde soeben verzeichnet " + +#: templates/email/recording/shared_data_recorded.html:14 +msgid "This means the data is now publicly available, e.g. in LANIS" +msgstr "" +"Das bedeutet, dass die Daten nun öffentlich verfügbar sind, z.B. im LANIS." + +#: templates/email/recording/shared_data_recorded.html:24 +msgid "" +"Please note: Recorded intervention means the compensations are recorded as " +"well." +msgstr "" +"Bitte beachten Sie: Verzeichnete Eingriffe bedeuten, dass auch die " +"zugehörigen Kompensationen automatisch verzeichnet sind." + +#: templates/email/recording/shared_data_unrecorded.html:4 +msgid "Shared data unrecorded" +msgstr "Freigegebene Daten entzeichnet" + +#: templates/email/recording/shared_data_unrecorded.html:10 +msgid "the following dataset has just been unrecorded" +msgstr "der folgende Datensatz wurde soeben entzeichnet " + +#: templates/email/recording/shared_data_unrecorded.html:14 +msgid "This means the data is no longer publicly available." +msgstr "Das bedeutet, dass die Daten nicht länger öffentlich verfügbar sind." + +#: templates/email/recording/shared_data_unrecorded.html:24 +msgid "" +"Please note: Unrecorded intervention means the compensations are unrecorded " +"as well." +msgstr "" +"Bitte beachten Sie: Entzeichnete Eingriffe bedeuten, dass auch die " +"zugehörigen Kompensationen automatisch entzeichnet worden sind." + +#: templates/email/sharing/shared_access_given.html:4 +msgid "Access shared" +msgstr "Zugriff freigegeben" + +#: templates/email/sharing/shared_access_given.html:10 +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:14 +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:15 +msgid "" +"The shared dataset appears now by default on your overview for this dataset " +"type." +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:25 +msgid "" +"Please note: Shared access on an intervention means you automatically have " +"editing access to related compensations." +msgstr "" +"Bitte beachten Sie: Freigegebener Zugriff auf einen Eingriff bedeutet, dass " +"Sie automatisch auch Zugriff auf die zugehörigen Kompensationen erhalten " +"haben." + +#: templates/email/sharing/shared_access_removed.html:4 +msgid "Shared access removed" +msgstr "Freigegebener Zugriff entzogen" + +#: templates/email/sharing/shared_access_removed.html:10 +msgid "" +"your shared access, including editing, has been revoked for the dataset " +msgstr "" +"Ihnen wurde soeben der bearbeitende Zugriff auf den folgenden Datensatz " +"entzogen: " + +#: templates/email/sharing/shared_access_removed.html:14 +msgid "However, you are still able to view the dataset content." +msgstr "Sie können den Datensatz aber immer noch im KSP einsehen." + +#: templates/email/sharing/shared_access_removed.html:15 +msgid "" +"Please use the provided search filter on the dataset`s overview pages to " +"find them." +msgstr "" +"Nutzen Sie hierzu einfach die entsprechenden Suchfilter auf den " +"Übersichtsseiten" + +#: templates/email/signature.html:6 +msgid "Please do not reply on this mail." +msgstr "Bitte antworten Sie nicht auf diese Mail." + +#: templates/email/signature.html:8 +msgid "If needed, please contact " +msgstr "Bei Rückfragen, wenden Sie sich bitte an " + #: templates/footer.html:6 msgid "Help" msgstr "Hilfe" @@ -1906,35 +2088,35 @@ msgstr "Abbrechen" msgid "Fields with * are required." msgstr "* sind Pflichtfelder." -#: templates/generic_index.html:28 +#: templates/generic_index.html:39 msgid "New entry" msgstr "Neuer Eintrag" -#: templates/generic_index.html:30 +#: templates/generic_index.html:41 msgid "New" msgstr "Neu" -#: templates/generic_index.html:45 +#: templates/generic_index.html:56 msgid "Search for keywords" msgstr "Nach Schlagwörtern suchen" -#: templates/generic_index.html:45 +#: templates/generic_index.html:56 msgid "Search" msgstr "Suchen" -#: templates/generic_index.html:46 +#: templates/generic_index.html:57 msgid "Start search" msgstr "Starte Suche" -#: templates/generic_index.html:58 +#: templates/generic_index.html:69 msgid "Results per page" msgstr "Treffer pro Seite" -#: templates/generic_index.html:82 templates/generic_index.html:99 +#: templates/generic_index.html:93 templates/generic_index.html:118 msgid "Filter" msgstr "" -#: templates/generic_index.html:101 +#: templates/generic_index.html:120 msgid "Apply filter" msgstr "Filter anwenden" @@ -2015,31 +2197,31 @@ msgstr "Wann wollen Sie per E-Mail benachrichtigt werden?" msgid "Edit notifications" msgstr "Benachrichtigungen bearbeiten" -#: user/forms.py:76 user/templates/user/index.html:9 +#: user/forms.py:72 user/templates/user/index.html:9 msgid "Username" msgstr "Nutzername" -#: user/forms.py:87 +#: user/forms.py:83 msgid "Person name" msgstr "Name" -#: user/forms.py:98 user/templates/user/index.html:17 +#: user/forms.py:94 user/templates/user/index.html:17 msgid "E-Mail" msgstr "" -#: user/forms.py:112 +#: user/forms.py:108 msgid "User contact data" msgstr "Kontaktdaten" -#: user/models/user_action.py:21 +#: user/models/user_action.py:20 msgid "Unrecorded" msgstr "Entzeichnet" -#: user/models/user_action.py:23 +#: user/models/user_action.py:22 msgid "Edited" msgstr "Bearbeitet" -#: user/models/user_action.py:24 +#: user/models/user_action.py:23 msgid "Deleted" msgstr "Gelöscht" @@ -2084,7 +2266,7 @@ msgstr "Benachrichtigungseinstellungen ändern" msgid "Notification settings" msgstr "Benachrichtigungen" -#: user/views.py:56 +#: user/views.py:52 msgid "Notifications edited" msgstr "Benachrichtigungen bearbeitet" @@ -3591,6 +3773,18 @@ msgstr "" msgid "Unable to connect to qpid with SASL mechanism %s" msgstr "" +#~ msgid "On registered data edited" +#~ msgstr "Wenn meine freigegebenen Daten bearbeitet wurden" + +#~ msgid "Not recorded" +#~ msgstr "Noch nicht verzeichnet" + +#~ msgid "On new related data" +#~ msgstr "Wenn neue Daten für mich angelegt werden" + +#~ msgid "On disabled share link" +#~ msgstr "Wenn ein Freigabelink deaktiviert wird" + #~ msgid "Deduct" #~ msgstr "Abbuchen" diff --git a/templates/email/checking/shared_data_checked.html b/templates/email/checking/shared_data_checked.html new file mode 100644 index 0000000..ccc0bbf --- /dev/null +++ b/templates/email/checking/shared_data_checked.html @@ -0,0 +1,26 @@ +{% load i18n %} + +
+

{% trans 'Shared data checked' %}

+

{{obj_identifier}}

+
+
+ {% trans 'Hello ' %} {{user.username}}, +
+ {% trans 'the following dataset has just been checked' %} +
+ '{{obj_identifier}}' +
+ {% trans 'This means, the responsible registration office just confirmed the correctness of this dataset.' %} +
+
+ {% trans 'Best regards' %} +
+ KSP +
+
+
+ {% include 'email/signature.html' %} +
+
+ diff --git a/templates/email/deleting/shared_data_deleted.html b/templates/email/deleting/shared_data_deleted.html new file mode 100644 index 0000000..36c80b0 --- /dev/null +++ b/templates/email/deleting/shared_data_deleted.html @@ -0,0 +1,26 @@ +{% load i18n %} + +
+

{% trans 'Shared data deleted' %}

+

{{obj_identifier}}

+
+
+ {% trans 'Hello ' %} {{user.username}}, +
+ {% trans 'the following dataset has just been deleted' %} +
+ '{{obj_identifier}}' +
+ {% trans 'If this should not have been happened, please contact us. See the signature for details.' %} +
+
+ {% trans 'Best regards' %} +
+ KSP +
+
+
+ {% include 'email/signature.html' %} +
+
+ diff --git a/templates/email/recording/shared_data_recorded.html b/templates/email/recording/shared_data_recorded.html new file mode 100644 index 0000000..82d236d --- /dev/null +++ b/templates/email/recording/shared_data_recorded.html @@ -0,0 +1,31 @@ +{% load i18n %} + +
+

{% trans 'Shared data recorded' %}

+

{{obj_identifier}}

+
+
+ {% trans 'Hello ' %} {{user.username}}, +
+ {% trans 'the following dataset has just been recorded' %} +
+ '{{obj_identifier}}' +
+ {% trans 'This means the data is now publicly available, e.g. in LANIS' %} +
+
+ {% trans 'Best regards' %} +
+ KSP +
+
+
+ + {% trans 'Please note: Recorded intervention means the compensations are recorded as well.' %} + +
+
+ {% include 'email/signature.html' %} +
+
+ diff --git a/templates/email/recording/shared_data_unrecorded.html b/templates/email/recording/shared_data_unrecorded.html new file mode 100644 index 0000000..a40e7ce --- /dev/null +++ b/templates/email/recording/shared_data_unrecorded.html @@ -0,0 +1,31 @@ +{% load i18n %} + +
+

{% trans 'Shared data unrecorded' %}

+

{{obj_identifier}}

+
+
+ {% trans 'Hello ' %} {{user.username}}, +
+ {% trans 'the following dataset has just been unrecorded' %} +
+ '{{obj_identifier}}' +
+ {% trans 'This means the data is no longer publicly available.' %} +
+
+ {% trans 'Best regards' %} +
+ KSP +
+
+
+ + {% trans 'Please note: Unrecorded intervention means the compensations are unrecorded as well.' %} + +
+
+ {% include 'email/signature.html' %} +
+
+ diff --git a/templates/email/sharing/shared_access_given.html b/templates/email/sharing/shared_access_given.html new file mode 100644 index 0000000..bf93e86 --- /dev/null +++ b/templates/email/sharing/shared_access_given.html @@ -0,0 +1,32 @@ +{% load i18n %} + +
+

{% trans 'Access shared' %}

+

{{obj_identifier}}

+
+
+ {% trans 'Hello ' %} {{user.username}}, +
+ {% trans 'the following dataset has just been shared with you' %} +
+ '{{obj_identifier}}' +
+ {% trans 'This means you can now edit this dataset.' %} + {% trans 'The shared dataset appears now by default on your overview for this dataset type.' %} +
+
+ {% trans 'Best regards' %} +
+ KSP +
+
+
+ + {% trans 'Please note: Shared access on an intervention means you automatically have editing access to related compensations.' %} + +
+
+ {% include 'email/signature.html' %} +
+
+ diff --git a/templates/email/sharing/shared_access_removed.html b/templates/email/sharing/shared_access_removed.html new file mode 100644 index 0000000..be6a4d6 --- /dev/null +++ b/templates/email/sharing/shared_access_removed.html @@ -0,0 +1,27 @@ +{% load i18n %} + +
+

{% trans 'Shared access removed' %}

+

{{obj_identifier}}

+
+
+ {% trans 'Hello ' %} {{user.username}}, +
+ {% trans 'your shared access, including editing, has been revoked for the dataset ' %} +
+ '{{obj_identifier}}' +
+ {% 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.' %} +
+
+ {% trans 'Best regards' %} +
+ KSP +
+
+
+ {% include 'email/signature.html' %} +
+
+ diff --git a/templates/email/signature.html b/templates/email/signature.html new file mode 100644 index 0000000..48f0909 --- /dev/null +++ b/templates/email/signature.html @@ -0,0 +1,10 @@ +{% load i18n %} + +
+
+ + {% trans 'Please do not reply on this mail.' %} +
+ {% trans 'If needed, please contact ' %} {{EMAIL_REPLY_TO}}. +
+
\ No newline at end of file diff --git a/user/admin.py b/user/admin.py index 9a633e7..92266b9 100644 --- a/user/admin.py +++ b/user/admin.py @@ -1,6 +1,6 @@ from django.contrib import admin -from user.models import UserNotification, KonovaUserExtension, UserActionLogEntry +from user.models import UserNotification, UserActionLogEntry, User class UserNotificationAdmin(admin.ModelAdmin): @@ -11,9 +11,13 @@ class UserNotificationAdmin(admin.ModelAdmin): ] -class KonovaUserExtensionAdmin(admin.ModelAdmin): +class UserAdmin(admin.ModelAdmin): list_display = [ - "user", + "id", + "username", + "first_name", + "last_name", + "email", ] @@ -27,5 +31,5 @@ class UserActionLogEntryAdmin(admin.ModelAdmin): admin.site.register(UserNotification, UserNotificationAdmin) -admin.site.register(KonovaUserExtension, KonovaUserExtensionAdmin) -admin.site.register(UserActionLogEntry, UserActionLogEntryAdmin) \ No newline at end of file +admin.site.register(UserActionLogEntry, UserActionLogEntryAdmin) +admin.site.register(User, UserAdmin) \ No newline at end of file diff --git a/user/enums.py b/user/enums.py index 1575a77..8d0c34d 100644 --- a/user/enums.py +++ b/user/enums.py @@ -9,9 +9,8 @@ from konova.enums import BaseEnum class UserNotificationEnum(BaseEnum): - NOTIFY_ON_NEW_RELATED_DATA = "NOTIFY_ON_NEW_RELATED_DATA" # notifies in case new data has been added which is related to the user's organisation - NOTIFY_ON_SHARE_LINK_DISABLED = "NOTIFY_ON_SHARE_LINK_DISABLED" # notifies in case share link for data has been disabled NOTIFY_ON_SHARED_ACCESS_REMOVED = "NOTIFY_ON_SHARED_ACCESS_REMOVED" # notifies in case shared access to data has been removed NOTIFY_ON_SHARED_DATA_RECORDED = "NOTIFY_ON_SHARED_DATA_RECORDED" # notifies in case data has been "verzeichnet" NOTIFY_ON_SHARED_DATA_DELETED = "NOTIFY_ON_SHARED_DATA_DELETED" # notifies in case data has been deleted - NOTIFY_ON_REGISTERED_DATA_EDITED = "NOTIFY_ON_REGISTERED_DATA_EDITED" # notifies in case registered ("verzeichnet") data has been edited \ No newline at end of file + NOTIFY_ON_SHARED_DATA_CHECKED = "NOTIFY_ON_SHARED_DATA_CHECKED" # notifies in case shared data has been checked + NOTIFY_ON_SHARED_ACCESS_GAINED = "NOTIFY_ON_SHARED_ACCESS_GAINED" # notifies in case new access has been gained \ No newline at end of file diff --git a/user/forms.py b/user/forms.py index 6d6accb..66f9fab 100644 --- a/user/forms.py +++ b/user/forms.py @@ -8,10 +8,10 @@ Created on: 08.07.21 from django import forms from django.urls import reverse from django.utils.translation import gettext_lazy as _ -from django.contrib.auth.models import User +from user.models import User from konova.forms import BaseForm, BaseModalForm -from user.models import UserNotification, KonovaUserExtension +from user.models import UserNotification class UserNotificationForm(BaseForm): @@ -50,11 +50,7 @@ class UserNotificationForm(BaseForm): ) self.fields["notifications"].choices = choices - # Set currently selected notifications as initial - self.konova_extension = KonovaUserExtension.objects.get_or_create( - user=user - )[0] - users_current_notifications = self.konova_extension.notifications.all() + users_current_notifications = self.user.notifications.all() users_current_notifications = [str(n.id) for n in users_current_notifications] self.fields["notifications"].initial = users_current_notifications @@ -68,7 +64,7 @@ class UserNotificationForm(BaseForm): notifications = UserNotification.objects.filter( id__in=selected_notification_ids, ) - self.konova_extension.notifications.set(notifications) + self.user.notifications.set(notifications) class UserContactForm(BaseModalForm): diff --git a/user/models/__init__.py b/user/models/__init__.py index 85a98b6..7788d8e 100644 --- a/user/models/__init__.py +++ b/user/models/__init__.py @@ -6,5 +6,5 @@ Created on: 15.11.21 """ from .user_action import * -from .konova_user import * +from .user import * from .notification import * diff --git a/user/models/konova_user.py b/user/models/konova_user.py deleted file mode 100644 index b100e02..0000000 --- a/user/models/konova_user.py +++ /dev/null @@ -1,19 +0,0 @@ -""" -Author: Michel Peltriaux -Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany -Contact: michel.peltriaux@sgdnord.rlp.de -Created on: 15.11.21 - -""" -from django.contrib.auth.models import User -from django.db import models - - -class KonovaUserExtension(models.Model): - """ Extension model for additional ksp features - - Extends the default user model for some extras - - """ - user = models.OneToOneField(User, on_delete=models.CASCADE) - notifications = models.ManyToManyField("user.UserNotification", related_name="+") diff --git a/user/models/user.py b/user/models/user.py new file mode 100644 index 0000000..837f0c6 --- /dev/null +++ b/user/models/user.py @@ -0,0 +1,106 @@ +""" +Author: Michel Peltriaux +Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany +Contact: michel.peltriaux@sgdnord.rlp.de +Created on: 15.11.21 + +""" +from django.contrib.auth.models import AbstractUser + +from django.db import models + +from konova.utils.mailer import Mailer +from user.enums import UserNotificationEnum + + +class User(AbstractUser): + notifications = models.ManyToManyField("user.UserNotification", related_name="+", blank=True) + + def is_notification_setting_set(self, notification_enum: UserNotificationEnum): + return self.notifications.filter( + id=notification_enum.value + ).exists() + + def send_mail_shared_access_removed(self, obj_identifier): + """ Sends a mail to the user in case of removed shared access + + Args: + obj_identifier (): + + Returns: + + """ + 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, self) + + def send_mail_shared_access_given(self, obj_identifier): + """ Sends a mail to the user in case of given shared access + + Args: + obj_identifier (): + + Returns: + + """ + 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, self) + + def send_mail_shared_data_recorded(self, obj_identifier): + """ Sends a mail to the user in case of shared data has been recorded + + Args: + obj_identifier (): + + Returns: + + """ + 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, self) + + def send_mail_shared_data_unrecorded(self, obj_identifier): + """ Sends a mail to the user in case of shared data has been unrecorded + + Args: + obj_identifier (): + + Returns: + + """ + 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, self) + + def send_mail_shared_data_deleted(self, obj_identifier): + """ Sends a mail to the user in case of shared data has been deleted + + Args: + obj_identifier (): + + Returns: + + """ + 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, self) + + def send_mail_shared_data_checked(self, obj_identifier): + """ Sends a mail to the user in case of shared data has been deleted + + Args: + obj_identifier (): + + Returns: + + """ + 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, self) diff --git a/user/models/user_action.py b/user/models/user_action.py index c1894f7..d902c5d 100644 --- a/user/models/user_action.py +++ b/user/models/user_action.py @@ -7,7 +7,6 @@ Created on: 15.11.21 """ import uuid -from django.contrib.auth.models import User from django.db import models from django.utils.translation import gettext_lazy as _ @@ -34,7 +33,7 @@ class UserActionLogEntry(models.Model): primary_key=True, default=uuid.uuid4, ) - user = models.ForeignKey(User, related_name='+', on_delete=models.CASCADE, help_text="Performing user") + user = models.ForeignKey("user.User", related_name='+', on_delete=models.CASCADE, help_text="Performing user") timestamp = models.DateTimeField(auto_now_add=True, help_text="Timestamp of performed action") action = models.CharField( max_length=255, @@ -50,9 +49,6 @@ class UserActionLogEntry(models.Model): "-timestamp", ) - def __str__(self): - return "{} | {} | {}".format(self.user.username, self.timestamp, self.action) - @property def action_humanize(self): """ Returns humanized version of enum @@ -69,7 +65,7 @@ class UserActionLogEntry(models.Model): return None @classmethod - def get_created_action(cls, user: User, comment: str = None): + def get_created_action(cls, user, comment: str = None): action = UserActionLogEntry.objects.create( user=user, action=UserAction.CREATED, @@ -78,7 +74,7 @@ class UserActionLogEntry(models.Model): return action @classmethod - def get_edited_action(cls, user: User, comment: str = None): + def get_edited_action(cls, user, comment: str = None): action = UserActionLogEntry.objects.create( user=user, action=UserAction.EDITED, @@ -87,7 +83,7 @@ class UserActionLogEntry(models.Model): return action @classmethod - def get_deleted_action(cls, user: User, comment: str = None): + def get_deleted_action(cls, user, comment: str = None): action = UserActionLogEntry.objects.create( user=user, action=UserAction.DELETED, @@ -96,7 +92,7 @@ class UserActionLogEntry(models.Model): return action @classmethod - def get_checked_action(cls, user: User, comment: str = None): + def get_checked_action(cls, user, comment: str = None): action = UserActionLogEntry.objects.create( user=user, action=UserAction.CHECKED, @@ -105,7 +101,7 @@ class UserActionLogEntry(models.Model): return action @classmethod - def get_recorded_action(cls, user: User, comment: str = None): + def get_recorded_action(cls, user, comment: str = None): action = UserActionLogEntry.objects.create( user=user, action=UserAction.RECORDED, @@ -114,7 +110,7 @@ class UserActionLogEntry(models.Model): return action @classmethod - def get_unrecorded_action(cls, user: User, comment: str = None): + def get_unrecorded_action(cls, user, comment: str = None): action = UserActionLogEntry.objects.create( user=user, action=UserAction.UNRECORDED, diff --git a/user/views.py b/user/views.py index f63b14b..13fecf5 100644 --- a/user/views.py +++ b/user/views.py @@ -1,6 +1,6 @@ from django.contrib import messages from django.contrib.auth.decorators import login_required -from django.contrib.auth.models import User +from user.models import User from django.http import HttpRequest from django.shortcuts import render, redirect, get_object_or_404 from django.utils.translation import gettext_lazy as _ @@ -8,7 +8,6 @@ from django.utils.translation import gettext_lazy as _ from konova.contexts import BaseContext from konova.decorators import any_group_check from user.forms import UserNotificationForm, UserContactForm -from user.models import KonovaUserExtension @login_required @@ -43,9 +42,6 @@ def notifications_view(request: HttpRequest): """ template = "user/notifications.html" user = request.user - konova_ext = KonovaUserExtension.objects.get_or_create( - user=user - )[0] form = UserNotificationForm(user=user, data=request.POST or None) if request.method == "POST": @@ -65,7 +61,6 @@ def notifications_view(request: HttpRequest): context = { "user": user, "form": form, - "konova_ext": konova_ext, } context = BaseContext(request, context).context return render(request, template, context)