Merge pull request '63_Email' (#65) from 63_Email into master

Reviewed-on: SGD-Nord/konova#65
This commit is contained in:
Michel Peltriaux 2022-01-12 16:04:42 +01:00
commit 6342044ff9
38 changed files with 833 additions and 169 deletions

View File

@ -6,7 +6,7 @@ Created on: 04.12.20
""" """
from dal import autocomplete from dal import autocomplete
from django.contrib.auth.models import User from user.models import User
from django.db import transaction from django.db import transaction
from django.urls import reverse_lazy, reverse from django.urls import reverse_lazy, reverse
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _

View File

@ -8,7 +8,7 @@ Created on: 16.11.21
import shutil import shutil
from django.contrib import messages 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 import models, transaction
from django.db.models import QuerySet, Sum from django.db.models import QuerySet, Sum
from django.http import HttpRequest from django.http import HttpRequest

View File

@ -7,7 +7,7 @@ Created on: 16.11.21
""" """
import shutil import shutil
from django.contrib.auth.models import User from user.models import User
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.core.validators import MinValueValidator from django.core.validators import MinValueValidator
from django.db import models, transaction from django.db import models, transaction

View File

@ -5,7 +5,7 @@ Contact: michel.peltriaux@sgdnord.rlp.de
Created on: 01.12.20 Created on: 01.12.20
""" """
from django.contrib.auth.models import User from user.models import User
from django.http import HttpRequest from django.http import HttpRequest
from django.template.loader import render_to_string from django.template.loader import render_to_string
from django.urls import reverse from django.urls import reverse

View File

@ -58,20 +58,8 @@ class EcoAccountQualityChecker(CompensationQualityChecker):
self._check_deductable_surface() self._check_deductable_surface()
self._check_responsible_data() self._check_responsible_data()
self._check_legal_data() self._check_legal_data()
self._check_record_state()
super().run_check() 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): def _check_legal_data(self):
""" Checks the data quality for Legal """ Checks the data quality for Legal

View File

@ -7,7 +7,7 @@ Created on: 06.10.21
""" """
from dal import autocomplete from dal import autocomplete
from django import forms from django import forms
from django.contrib.auth.models import User from user.models import User
from django.db import transaction from django.db import transaction
from django.urls import reverse, reverse_lazy from django.urls import reverse, reverse_lazy
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _

View File

@ -7,7 +7,7 @@ Created on: 02.12.20
""" """
from dal import autocomplete from dal import autocomplete
from django import forms from django import forms
from django.contrib.auth.models import User from user.models import User
from django.db import transaction from django.db import transaction
from django.urls import reverse, reverse_lazy from django.urls import reverse, reverse_lazy
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _

View File

@ -6,7 +6,7 @@ Created on: 27.09.21
""" """
from dal import autocomplete from dal import autocomplete
from django.contrib.auth.models import User from user.models import User
from django.db import transaction from django.db import transaction
from django import forms from django import forms
from django.urls import reverse from django.urls import reverse

View File

@ -8,7 +8,7 @@ Created on: 15.11.21
import shutil import shutil
from django.contrib import messages 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 import models, transaction
from django.db.models import QuerySet from django.db.models import QuerySet
from django.http import HttpRequest from django.http import HttpRequest

View File

@ -6,7 +6,7 @@ Created on: 07.12.20
""" """
from dal_select2.views import Select2QuerySetView, Select2GroupQuerySetView 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 django.db.models import Q
from codelist.models import KonovaCode from codelist.models import KonovaCode

View File

@ -12,7 +12,7 @@ from bootstrap_modal_forms.forms import BSModalForm
from bootstrap_modal_forms.utils import is_ajax from bootstrap_modal_forms.utils import is_ajax
from django import forms from django import forms
from django.contrib import messages 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.forms import OSMWidget, MultiPolygonField
from django.contrib.gis.geos import MultiPolygon from django.contrib.gis.geos import MultiPolygon
from django.db import transaction from django.db import transaction

View File

@ -7,7 +7,8 @@ Created on: 15.12.20
""" """
from getpass import getpass 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.core.management import BaseCommand, call_command
from django.db import transaction from django.db import transaction

View File

@ -23,10 +23,9 @@ GROUPS_DATA = [
# Must match with UserNotificationEnum # Must match with UserNotificationEnum
USER_NOTIFICATIONS_NAMES = { USER_NOTIFICATIONS_NAMES = {
"NOTIFY_ON_NEW_RELATED_DATA": _("On new related data"), "NOTIFY_ON_SHARED_ACCESS_GAINED": _("On shared access gained"),
"NOTIFY_ON_SHARE_LINK_DISABLED": _("On disabled share link"),
"NOTIFY_ON_SHARED_ACCESS_REMOVED": _("On shared access removed"), "NOTIFY_ON_SHARED_ACCESS_REMOVED": _("On shared access removed"),
"NOTIFY_ON_SHARED_DATA_RECORDED": _("On shared data recorded"), "NOTIFY_ON_SHARED_DATA_RECORDED": _("On shared data recorded"),
"NOTIFY_ON_SHARED_DATA_DELETED": _("On shared data deleted"), "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"),
} }

View File

@ -10,7 +10,11 @@ import uuid
from abc import abstractmethod from abc import abstractmethod
from django.contrib import messages 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.core.exceptions import ObjectDoesNotExist
from django.http import HttpRequest from django.http import HttpRequest
from django.utils.timezone import now from django.utils.timezone import now
@ -118,6 +122,12 @@ class BaseObject(BaseResource):
action = UserActionLogEntry.get_deleted_action(user) action = UserActionLogEntry.get_deleted_action(user)
self.deleted = action self.deleted = action
self.log.add(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() self.save()
def add_log_entry(self, action: UserAction, user: User, comment: str): def add_log_entry(self, action: UserAction, user: User, comment: str):
@ -216,6 +226,11 @@ class RecordableObjectMixin(models.Model):
self.recorded = None self.recorded = None
self.save() self.save()
self.log.add(action) 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 return action
def set_recorded(self, user: User): def set_recorded(self, user: User):
@ -233,6 +248,11 @@ class RecordableObjectMixin(models.Model):
self.recorded = action self.recorded = action
self.save() self.save()
self.log.add(action) 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 return action
def mark_as_edited(self, performing_user: User, request: HttpRequest = None, edit_comment: str = None): 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) action = UserActionLogEntry.get_checked_action(user)
self.checked = action self.checked = action
self.save() 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) self.log.add(action)
return action return action
@ -411,6 +437,17 @@ class ShareableObjectMixin(models.Model):
users = User.objects.filter( users = User.objects.filter(
id__in=accessing_users 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) self.share_with_list(users)

View File

@ -5,9 +5,10 @@ Contact: michel.peltriaux@sgdnord.rlp.de
Created on: 17.08.21 Created on: 17.08.21
""" """
from django.contrib.auth.models import User
from simple_sso.sso_client.client import Client from simple_sso.sso_client.client import Client
from user.models import User
class KonovaSSOClient(Client): class KonovaSSOClient(Client):
""" Konova specialized derivate of general sso.Client. """ Konova specialized derivate of general sso.Client.

View File

@ -129,7 +129,7 @@ DATABASES = {
# Password validation # Password validation
# https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators # https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators
AUTH_USER_MODEL = "user.User"
AUTH_PASSWORD_VALIDATORS = [ AUTH_PASSWORD_VALIDATORS = [
{ {
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
@ -204,9 +204,15 @@ DEBUG_TOOLBAR_CONFIG = {
} }
# EMAIL (see https://docs.djangoproject.com/en/dev/topics/email/) # 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_HOST = "localhost"
EMAIL_PORT = "1025" EMAIL_REPLY_TO = "ksp-servicestelle@sgdnord.rlp.de"
EMAIL_PORT = "25"
#EMAIL_HOST_USER = "" #EMAIL_HOST_USER = ""
#EMAIL_HOST_PASSWORD = "" #EMAIL_HOST_PASSWORD = ""
EMAIL_USE_TLS = False EMAIL_USE_TLS = False

View File

@ -1,14 +1,60 @@
from time import sleep
from celery import shared_task from celery import shared_task
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from konova.models import Geometry
@shared_task @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: try:
geom = Geometry.objects.get(id=geometry_id) geom = Geometry.objects.get(id=geometry_id)
geom.parcels.clear() geom.parcels.clear()
geom.update_parcels() geom.update_parcels()
except ObjectDoesNotExist: 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)

View File

@ -7,7 +7,8 @@ Created on: 26.10.21
""" """
import datetime 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.contrib.gis.geos import MultiPolygon, Polygon
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from django.test import TestCase, Client from django.test import TestCase, Client

View File

@ -8,8 +8,10 @@ Created on: 09.11.20
import logging import logging
from django.core.mail import send_mail 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__) logger = logging.getLogger(__name__)
@ -26,27 +28,156 @@ class Mailer:
auth_user = None auth_user = None
auth_password = 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): def __init__(self, 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]
self.from_mail = from_mail self.from_mail = from_mail
self.to_mail = to_mail
self.fail_silently = fail_silently self.fail_silently = fail_silently
self.auth_user = auth_user self.auth_user = auth_user
self.auth_password = auth_password 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 Sends a mail with subject and message
""" """
return send_mail( return send_mail(
subject=subject, subject=subject,
message=msg, message=None,
html_message=msg,
from_email=self.from_mail, from_email=self.from_mail,
recipient_list=self.to_mail, recipient_list=recipient_list,
fail_silently=self.fail_silently, fail_silently=self.fail_silently,
auth_user=self.auth_user, auth_user=self.auth_user,
auth_password=self.auth_password auth_password=self.auth_password
) )
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
)

View File

@ -8,7 +8,7 @@ Created on: 17.08.21
from collections import Iterable from collections import Iterable
import requests import requests
from django.contrib.auth.models import User from user.models import User
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from konova.settings import SSO_SERVER_BASE, SSO_PUBLIC_KEY, PROXIES from konova.settings import SSO_SERVER_BASE, SSO_PUBLIC_KEY, PROXIES

View File

@ -5,7 +5,7 @@ Contact: michel.peltriaux@sgdnord.rlp.de
Created on: 02.07.21 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 from konova.settings import ETS_GROUP, ZB_GROUP

Binary file not shown.

View File

@ -3,26 +3,30 @@
# This file is distributed under the same license as the PACKAGE package. # This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. # FIRST AUTHOR <EMAIL@ADDRESS>, 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:45 compensation/forms/modalForms.py:61
#: compensation/forms/modalForms.py:238 compensation/forms/modalForms.py:316 #: compensation/forms/modalForms.py:238 compensation/forms/modalForms.py:316
#: intervention/forms/forms.py:52 intervention/forms/forms.py:154 #: intervention/forms/forms.py:52 intervention/forms/forms.py:154
#: intervention/forms/forms.py:166 intervention/forms/modalForms.py:125 #: intervention/forms/forms.py:166 intervention/forms/modalForms.py:125
#: intervention/forms/modalForms.py:138 intervention/forms/modalForms.py:151 #: intervention/forms/modalForms.py:138 intervention/forms/modalForms.py:151
#: konova/filters.py:63 konova/filters.py:64 konova/filters.py:91 #: konova/filters/mixins.py:53 konova/filters/mixins.py:54
#: konova/filters.py:92 konova/filters.py:104 konova/filters.py:105 #: konova/filters/mixins.py:81 konova/filters/mixins.py:82
#: konova/filters.py:117 konova/filters.py:118 konova/filters.py:130 #: konova/filters/mixins.py:94 konova/filters/mixins.py:95
#: konova/filters.py:131 konova/filters.py:144 konova/filters.py:145 #: konova/filters/mixins.py:107 konova/filters/mixins.py:108
#: konova/filters.py:280 konova/filters.py:324 konova/forms.py:140 #: konova/filters/mixins.py:120 konova/filters/mixins.py:121
#: konova/forms.py:241 konova/forms.py:312 konova/forms.py:339 #: konova/filters/mixins.py:134 konova/filters/mixins.py:135
#: konova/forms.py:349 konova/forms.py:362 konova/forms.py:374 #: konova/filters/mixins.py:270 konova/filters/mixins.py:315
#: konova/forms.py:392 user/forms.py:38 #: 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 #, fuzzy
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \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" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -43,12 +47,12 @@ msgstr "Bis"
#: analysis/forms.py:47 compensation/forms/forms.py:77 #: analysis/forms.py:47 compensation/forms/forms.py:77
#: compensation/templates/compensation/detail/eco_account/view.html:58 #: compensation/templates/compensation/detail/eco_account/view.html:58
#: compensation/templates/compensation/report/eco_account/report.html:16 #: 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 #: ema/templates/ema/report/report.html:16 ema/utils/quality.py:26
#: intervention/forms/forms.py:100 #: intervention/forms/forms.py:100
#: intervention/templates/intervention/detail/view.html:56 #: intervention/templates/intervention/detail/view.html:56
#: intervention/templates/intervention/report/report.html:37 #: 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" msgid "Conservation office"
msgstr "Eintragungsstelle" msgstr "Eintragungsstelle"
@ -136,7 +140,7 @@ msgstr "Zuständigkeitsbereich"
#: compensation/templates/compensation/detail/compensation/view.html:63 #: compensation/templates/compensation/detail/compensation/view.html:63
#: intervention/tables.py:33 #: intervention/tables.py:33
#: intervention/templates/intervention/detail/view.html:68 #: intervention/templates/intervention/detail/view.html:68
#: user/models/user_action.py:19 #: user/models/user_action.py:18
msgid "Checked" msgid "Checked"
msgstr "Geprüft" msgstr "Geprüft"
@ -155,7 +159,7 @@ msgstr "Geprüft"
#: ema/tables.py:38 ema/templates/ema/detail/view.html:35 #: ema/tables.py:38 ema/templates/ema/detail/view.html:35
#: intervention/tables.py:39 #: intervention/tables.py:39
#: intervention/templates/intervention/detail/view.html:82 #: intervention/templates/intervention/detail/view.html:82
#: user/models/user_action.py:20 #: user/models/user_action.py:19
msgid "Recorded" msgid "Recorded"
msgstr "Verzeichnet" msgstr "Verzeichnet"
@ -301,7 +305,7 @@ msgstr "Altfälle"
msgid "Before" msgid "Before"
msgstr "Vor" msgstr "Vor"
#: compensation/filters.py:90 #: compensation/filters.py:121
msgid "Show only unrecorded" msgid "Show only unrecorded"
msgstr "Nur unverzeichnete anzeigen" msgstr "Nur unverzeichnete anzeigen"
@ -370,7 +374,7 @@ msgstr "Zusätzlicher Kommentar"
#: compensation/forms/forms.py:93 #: compensation/forms/forms.py:93
#: compensation/templates/compensation/detail/eco_account/view.html:62 #: compensation/templates/compensation/detail/eco_account/view.html:62
#: compensation/templates/compensation/report/eco_account/report.html:20 #: 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 #: ema/templates/ema/report/report.html:20 ema/utils/quality.py:28
#: intervention/forms/forms.py:128 #: intervention/forms/forms.py:128
#: intervention/templates/intervention/detail/view.html:60 #: intervention/templates/intervention/detail/view.html:60
@ -430,7 +434,7 @@ msgstr "Neue Kompensation"
msgid "Edit compensation" msgid "Edit compensation"
msgstr "Bearbeite Kompensation" 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" msgid "Available Surface"
msgstr "Verfügbare Fläche" 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/forms/forms.py:314
#: compensation/templates/compensation/detail/eco_account/view.html:66 #: compensation/templates/compensation/detail/eco_account/view.html:66
#: compensation/utils/quality.py:84 #: compensation/utils/quality.py:72
msgid "Agreement date" msgid "Agreement date"
msgstr "Vereinbarungsdatum" msgstr "Vereinbarungsdatum"
@ -958,7 +962,7 @@ msgstr "Eingriffskennung"
#: compensation/templates/compensation/detail/eco_account/includes/deductions.html:37 #: compensation/templates/compensation/detail/eco_account/includes/deductions.html:37
#: intervention/templates/intervention/detail/includes/deductions.html:34 #: intervention/templates/intervention/detail/includes/deductions.html:34
#: user/models/user_action.py:22 #: user/models/user_action.py:21
msgid "Created" msgid "Created"
msgstr "Erstellt" msgstr "Erstellt"
@ -1036,21 +1040,17 @@ msgstr "-"
msgid "States unequal" msgid "States unequal"
msgstr "Ungleiche Zustandsflächenmengen" msgstr "Ungleiche Zustandsflächenmengen"
#: compensation/utils/quality.py:72 #: compensation/utils/quality.py:74 intervention/utils/quality.py:84
msgid "Not recorded"
msgstr "Noch nicht verzeichnet"
#: compensation/utils/quality.py:86 intervention/utils/quality.py:84
msgid "Legal data" msgid "Legal data"
msgstr "Rechtliche Daten" msgstr "Rechtliche Daten"
#: compensation/utils/quality.py:100 #: compensation/utils/quality.py:88
msgid "Deductable surface can not be larger than state surface" msgid "Deductable surface can not be larger than state surface"
msgstr "" msgstr ""
"Die abbuchbare Fläche darf die Gesamtfläche der Zielzustände nicht " "Die abbuchbare Fläche darf die Gesamtfläche der Zielzustände nicht "
"überschreiten" "ü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 #: intervention/utils/quality.py:55
msgid "Responsible data" msgid "Responsible data"
msgstr "Daten zu den verantwortlichen Stellen" msgstr "Daten zu den verantwortlichen Stellen"
@ -1218,7 +1218,7 @@ msgstr "Mehrfachauswahl möglich"
#: intervention/forms/forms.py:84 #: intervention/forms/forms.py:84
#: intervention/templates/intervention/detail/view.html:48 #: intervention/templates/intervention/detail/view.html:48
#: intervention/templates/intervention/report/report.html:29 #: 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" msgid "Registration office"
msgstr "Zulassungsbehörde" msgstr "Zulassungsbehörde"
@ -1508,62 +1508,73 @@ msgstr ""
"somit nichts eingeben, bearbeiten oder sonstige Aktionen ausführen. " "somit nichts eingeben, bearbeiten oder sonstige Aktionen ausführen. "
"Kontaktieren Sie bitte einen Administrator. +++" "Kontaktieren Sie bitte einen Administrator. +++"
#: konova/filters.py:67 #: konova/filters/mixins.py:57
msgid "File number" msgid "File number"
msgstr "Aktenzeichen" msgstr "Aktenzeichen"
#: konova/filters.py:68 #: konova/filters/mixins.py:58
msgid "Search for file number" msgid "Search for file number"
msgstr "Nach Aktenzeichen suchen" msgstr "Nach Aktenzeichen suchen"
#: konova/filters.py:95 #: konova/filters/mixins.py:85
msgid "District" msgid "District"
msgstr "Kreis" msgstr "Kreis"
#: konova/filters.py:96 #: konova/filters/mixins.py:86
msgid "Search for district" msgid "Search for district"
msgstr "Nach Kreis suchen" msgstr "Nach Kreis suchen"
#: konova/filters.py:108 #: konova/filters/mixins.py:98
msgid "Parcel gmrkng" msgid "Parcel gmrkng"
msgstr "Gemarkung" msgstr "Gemarkung"
#: konova/filters.py:109 #: konova/filters/mixins.py:99
msgid "Search for parcel gmrkng" msgid "Search for parcel gmrkng"
msgstr "Nach Gemarkung suchen" 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" msgid "Parcel"
msgstr "Flur" msgstr "Flur"
#: konova/filters.py:122 #: konova/filters/mixins.py:112
msgid "Search for parcel" msgid "Search for parcel"
msgstr "Nach Flur suchen" 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" msgid "Parcel counter"
msgstr "Flurstückzähler" msgstr "Flurstückzähler"
#: konova/filters.py:135 #: konova/filters/mixins.py:125
msgid "Search for parcel counter" msgid "Search for parcel counter"
msgstr "Nach Flurstückzähler suchen" 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" msgid "Parcel number"
msgstr "Flurstücknenner" msgstr "Flurstücknenner"
#: konova/filters.py:149 #: konova/filters/mixins.py:139
msgid "Search for parcel number" msgid "Search for parcel number"
msgstr "Nach Flurstücknenner suchen" msgstr "Nach Flurstücknenner suchen"
#: konova/filters.py:279 #: konova/filters/mixins.py:269
msgid "Show unshared" msgid "Show unshared"
msgstr "Nicht freigegebene anzeigen" msgstr "Nicht freigegebene anzeigen"
#: konova/filters.py:323 #: konova/filters/mixins.py:314
msgid "Show recorded" msgid "Show recorded"
msgstr "Verzeichnete anzeigen" 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 #: konova/forms.py:37 templates/form/collapsable/form.html:62
msgid "Save" msgid "Save"
msgstr "Speichern" msgstr "Speichern"
@ -1644,28 +1655,24 @@ msgstr ""
"Ich, {} {}, bestätige, dass diese Daten wieder entzeichnet werden müssen." "Ich, {} {}, bestätige, dass diese Daten wieder entzeichnet werden müssen."
#: konova/management/commands/setup_data.py:26 #: konova/management/commands/setup_data.py:26
msgid "On new related data" msgid "On shared access gained"
msgstr "Wenn neue Daten für mich angelegt werden" msgstr "Wenn mir eine Freigabe zu Daten erteilt wird"
#: konova/management/commands/setup_data.py:27 #: 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" msgid "On shared access removed"
msgstr "Wenn mir eine Freigabe zu Daten entzogen wird" 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" msgid "On shared data recorded"
msgstr "Wenn meine freigegebenen Daten verzeichnet wurden" 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" msgid "On shared data deleted"
msgstr "Wenn meine freigegebenen Daten gelöscht wurden" msgstr "Wenn meine freigegebenen Daten gelöscht wurden"
#: konova/management/commands/setup_data.py:31 #: konova/management/commands/setup_data.py:30
msgid "On registered data edited" msgid "On shared data checked"
msgstr "Wenn meine freigegebenen Daten bearbeitet wurden" msgstr "Wenn meine freigegebenen Daten geprüft wurden"
#: konova/models/deadline.py:18 #: konova/models/deadline.py:18
msgid "Finished" msgid "Finished"
@ -1746,6 +1753,30 @@ msgstr "In Zwischenablage kopiert"
msgid "Document '{}' deleted" msgid "Document '{}' deleted"
msgstr "Dokument '{}' gelöscht" 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 #: konova/utils/message_templates.py:11
msgid "There was an error on this form." msgid "There was an error on this form."
msgstr "Es gab einen Fehler im Formular." msgstr "Es gab einen Fehler im Formular."
@ -1860,6 +1891,157 @@ msgstr "Alle"
msgid "News" msgid "News"
msgstr "Neuigkeiten" 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 #: templates/footer.html:6
msgid "Help" msgid "Help"
msgstr "Hilfe" msgstr "Hilfe"
@ -1906,35 +2088,35 @@ msgstr "Abbrechen"
msgid "Fields with * are required." msgid "Fields with * are required."
msgstr "* sind Pflichtfelder." msgstr "* sind Pflichtfelder."
#: templates/generic_index.html:28 #: templates/generic_index.html:39
msgid "New entry" msgid "New entry"
msgstr "Neuer Eintrag" msgstr "Neuer Eintrag"
#: templates/generic_index.html:30 #: templates/generic_index.html:41
msgid "New" msgid "New"
msgstr "Neu" msgstr "Neu"
#: templates/generic_index.html:45 #: templates/generic_index.html:56
msgid "Search for keywords" msgid "Search for keywords"
msgstr "Nach Schlagwörtern suchen" msgstr "Nach Schlagwörtern suchen"
#: templates/generic_index.html:45 #: templates/generic_index.html:56
msgid "Search" msgid "Search"
msgstr "Suchen" msgstr "Suchen"
#: templates/generic_index.html:46 #: templates/generic_index.html:57
msgid "Start search" msgid "Start search"
msgstr "Starte Suche" msgstr "Starte Suche"
#: templates/generic_index.html:58 #: templates/generic_index.html:69
msgid "Results per page" msgid "Results per page"
msgstr "Treffer pro Seite" 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" msgid "Filter"
msgstr "" msgstr ""
#: templates/generic_index.html:101 #: templates/generic_index.html:120
msgid "Apply filter" msgid "Apply filter"
msgstr "Filter anwenden" msgstr "Filter anwenden"
@ -2015,31 +2197,31 @@ msgstr "Wann wollen Sie per E-Mail benachrichtigt werden?"
msgid "Edit notifications" msgid "Edit notifications"
msgstr "Benachrichtigungen bearbeiten" 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" msgid "Username"
msgstr "Nutzername" msgstr "Nutzername"
#: user/forms.py:87 #: user/forms.py:83
msgid "Person name" msgid "Person name"
msgstr "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" msgid "E-Mail"
msgstr "" msgstr ""
#: user/forms.py:112 #: user/forms.py:108
msgid "User contact data" msgid "User contact data"
msgstr "Kontaktdaten" msgstr "Kontaktdaten"
#: user/models/user_action.py:21 #: user/models/user_action.py:20
msgid "Unrecorded" msgid "Unrecorded"
msgstr "Entzeichnet" msgstr "Entzeichnet"
#: user/models/user_action.py:23 #: user/models/user_action.py:22
msgid "Edited" msgid "Edited"
msgstr "Bearbeitet" msgstr "Bearbeitet"
#: user/models/user_action.py:24 #: user/models/user_action.py:23
msgid "Deleted" msgid "Deleted"
msgstr "Gelöscht" msgstr "Gelöscht"
@ -2084,7 +2266,7 @@ msgstr "Benachrichtigungseinstellungen ändern"
msgid "Notification settings" msgid "Notification settings"
msgstr "Benachrichtigungen" msgstr "Benachrichtigungen"
#: user/views.py:56 #: user/views.py:52
msgid "Notifications edited" msgid "Notifications edited"
msgstr "Benachrichtigungen bearbeitet" msgstr "Benachrichtigungen bearbeitet"
@ -3591,6 +3773,18 @@ msgstr ""
msgid "Unable to connect to qpid with SASL mechanism %s" msgid "Unable to connect to qpid with SASL mechanism %s"
msgstr "" 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" #~ msgid "Deduct"
#~ msgstr "Abbuchen" #~ msgstr "Abbuchen"

View File

@ -0,0 +1,26 @@
{% load i18n %}
<div>
<h2>{% trans 'Shared data checked' %}</h2>
<h4>{{obj_identifier}}</h4>
<hr>
<article>
{% trans 'Hello ' %} {{user.username}},
<br>
{% trans 'the following dataset has just been checked' %}
<br>
<strong>'{{obj_identifier}}'</strong>
<br>
{% trans 'This means, the responsible registration office just confirmed the correctness of this dataset.' %}
<br>
<br>
{% trans 'Best regards' %}
<br>
KSP
<br>
<br>
<br>
{% include 'email/signature.html' %}
</article>
</div>

View File

@ -0,0 +1,26 @@
{% load i18n %}
<div>
<h2>{% trans 'Shared data deleted' %}</h2>
<h4>{{obj_identifier}}</h4>
<hr>
<article>
{% trans 'Hello ' %} {{user.username}},
<br>
{% trans 'the following dataset has just been deleted' %}
<br>
<strong>'{{obj_identifier}}'</strong>
<br>
{% trans 'If this should not have been happened, please contact us. See the signature for details.' %}
<br>
<br>
{% trans 'Best regards' %}
<br>
KSP
<br>
<br>
<br>
{% include 'email/signature.html' %}
</article>
</div>

View File

@ -0,0 +1,31 @@
{% load i18n %}
<div>
<h2>{% trans 'Shared data recorded' %}</h2>
<h4>{{obj_identifier}}</h4>
<hr>
<article>
{% trans 'Hello ' %} {{user.username}},
<br>
{% trans 'the following dataset has just been recorded' %}
<br>
<strong>'{{obj_identifier}}'</strong>
<br>
{% trans 'This means the data is now publicly available, e.g. in LANIS' %}
<br>
<br>
{% trans 'Best regards' %}
<br>
KSP
<br>
<br>
<br>
<small>
{% trans 'Please note: Recorded intervention means the compensations are recorded as well.' %}
</small>
<br>
<br>
{% include 'email/signature.html' %}
</article>
</div>

View File

@ -0,0 +1,31 @@
{% load i18n %}
<div>
<h2>{% trans 'Shared data unrecorded' %}</h2>
<h4>{{obj_identifier}}</h4>
<hr>
<article>
{% trans 'Hello ' %} {{user.username}},
<br>
{% trans 'the following dataset has just been unrecorded' %}
<br>
<strong>'{{obj_identifier}}'</strong>
<br>
{% trans 'This means the data is no longer publicly available.' %}
<br>
<br>
{% trans 'Best regards' %}
<br>
KSP
<br>
<br>
<br>
<small>
{% trans 'Please note: Unrecorded intervention means the compensations are unrecorded as well.' %}
</small>
<br>
<br>
{% include 'email/signature.html' %}
</article>
</div>

View File

@ -0,0 +1,32 @@
{% load i18n %}
<div>
<h2>{% trans 'Access shared' %}</h2>
<h4>{{obj_identifier}}</h4>
<hr>
<article>
{% trans 'Hello ' %} {{user.username}},
<br>
{% trans 'the following dataset has just been shared with you' %}
<br>
<strong>'{{obj_identifier}}'</strong>
<br>
{% trans 'This means you can now edit this dataset.' %}
{% trans 'The shared dataset appears now by default on your overview for this dataset type.' %}
<br>
<br>
{% trans 'Best regards' %}
<br>
KSP
<br>
<br>
<br>
<small>
{% trans 'Please note: Shared access on an intervention means you automatically have editing access to related compensations.' %}
</small>
<br>
<br>
{% include 'email/signature.html' %}
</article>
</div>

View File

@ -0,0 +1,27 @@
{% load i18n %}
<div>
<h2>{% trans 'Shared access removed' %}</h2>
<h4>{{obj_identifier}}</h4>
<hr>
<article>
{% trans 'Hello ' %} {{user.username}},
<br>
{% trans 'your shared access, including editing, has been revoked for the dataset ' %}
<br>
<strong>'{{obj_identifier}}'</strong>
<br>
{% 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.' %}
<br>
<br>
{% trans 'Best regards' %}
<br>
KSP
<br>
<br>
<br>
{% include 'email/signature.html' %}
</article>
</div>

View File

@ -0,0 +1,10 @@
{% load i18n %}
<div>
<hr>
<small>
{% trans 'Please do not reply on this mail.' %}
<br>
{% trans 'If needed, please contact ' %} <a href="mailto:{{EMAIL_REPLY_TO}}">{{EMAIL_REPLY_TO}}</a>.
</small>
</div>

View File

@ -1,6 +1,6 @@
from django.contrib import admin from django.contrib import admin
from user.models import UserNotification, KonovaUserExtension, UserActionLogEntry from user.models import UserNotification, UserActionLogEntry, User
class UserNotificationAdmin(admin.ModelAdmin): class UserNotificationAdmin(admin.ModelAdmin):
@ -11,9 +11,13 @@ class UserNotificationAdmin(admin.ModelAdmin):
] ]
class KonovaUserExtensionAdmin(admin.ModelAdmin): class UserAdmin(admin.ModelAdmin):
list_display = [ 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(UserNotification, UserNotificationAdmin)
admin.site.register(KonovaUserExtension, KonovaUserExtensionAdmin)
admin.site.register(UserActionLogEntry, UserActionLogEntryAdmin) admin.site.register(UserActionLogEntry, UserActionLogEntryAdmin)
admin.site.register(User, UserAdmin)

View File

@ -9,9 +9,8 @@ from konova.enums import BaseEnum
class UserNotificationEnum(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_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_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_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 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

View File

@ -8,10 +8,10 @@ Created on: 08.07.21
from django import forms from django import forms
from django.urls import reverse from django.urls import reverse
from django.utils.translation import gettext_lazy as _ 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 konova.forms import BaseForm, BaseModalForm
from user.models import UserNotification, KonovaUserExtension from user.models import UserNotification
class UserNotificationForm(BaseForm): class UserNotificationForm(BaseForm):
@ -50,11 +50,7 @@ class UserNotificationForm(BaseForm):
) )
self.fields["notifications"].choices = choices self.fields["notifications"].choices = choices
# Set currently selected notifications as initial users_current_notifications = self.user.notifications.all()
self.konova_extension = KonovaUserExtension.objects.get_or_create(
user=user
)[0]
users_current_notifications = self.konova_extension.notifications.all()
users_current_notifications = [str(n.id) for n in users_current_notifications] users_current_notifications = [str(n.id) for n in users_current_notifications]
self.fields["notifications"].initial = users_current_notifications self.fields["notifications"].initial = users_current_notifications
@ -68,7 +64,7 @@ class UserNotificationForm(BaseForm):
notifications = UserNotification.objects.filter( notifications = UserNotification.objects.filter(
id__in=selected_notification_ids, id__in=selected_notification_ids,
) )
self.konova_extension.notifications.set(notifications) self.user.notifications.set(notifications)
class UserContactForm(BaseModalForm): class UserContactForm(BaseModalForm):

View File

@ -6,5 +6,5 @@ Created on: 15.11.21
""" """
from .user_action import * from .user_action import *
from .konova_user import * from .user import *
from .notification import * from .notification import *

View File

@ -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="+")

106
user/models/user.py Normal file
View File

@ -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)

View File

@ -7,7 +7,6 @@ Created on: 15.11.21
""" """
import uuid import uuid
from django.contrib.auth.models import User
from django.db import models from django.db import models
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
@ -34,7 +33,7 @@ class UserActionLogEntry(models.Model):
primary_key=True, primary_key=True,
default=uuid.uuid4, 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") timestamp = models.DateTimeField(auto_now_add=True, help_text="Timestamp of performed action")
action = models.CharField( action = models.CharField(
max_length=255, max_length=255,
@ -50,9 +49,6 @@ class UserActionLogEntry(models.Model):
"-timestamp", "-timestamp",
) )
def __str__(self):
return "{} | {} | {}".format(self.user.username, self.timestamp, self.action)
@property @property
def action_humanize(self): def action_humanize(self):
""" Returns humanized version of enum """ Returns humanized version of enum
@ -69,7 +65,7 @@ class UserActionLogEntry(models.Model):
return None return None
@classmethod @classmethod
def get_created_action(cls, user: User, comment: str = None): def get_created_action(cls, user, comment: str = None):
action = UserActionLogEntry.objects.create( action = UserActionLogEntry.objects.create(
user=user, user=user,
action=UserAction.CREATED, action=UserAction.CREATED,
@ -78,7 +74,7 @@ class UserActionLogEntry(models.Model):
return action return action
@classmethod @classmethod
def get_edited_action(cls, user: User, comment: str = None): def get_edited_action(cls, user, comment: str = None):
action = UserActionLogEntry.objects.create( action = UserActionLogEntry.objects.create(
user=user, user=user,
action=UserAction.EDITED, action=UserAction.EDITED,
@ -87,7 +83,7 @@ class UserActionLogEntry(models.Model):
return action return action
@classmethod @classmethod
def get_deleted_action(cls, user: User, comment: str = None): def get_deleted_action(cls, user, comment: str = None):
action = UserActionLogEntry.objects.create( action = UserActionLogEntry.objects.create(
user=user, user=user,
action=UserAction.DELETED, action=UserAction.DELETED,
@ -96,7 +92,7 @@ class UserActionLogEntry(models.Model):
return action return action
@classmethod @classmethod
def get_checked_action(cls, user: User, comment: str = None): def get_checked_action(cls, user, comment: str = None):
action = UserActionLogEntry.objects.create( action = UserActionLogEntry.objects.create(
user=user, user=user,
action=UserAction.CHECKED, action=UserAction.CHECKED,
@ -105,7 +101,7 @@ class UserActionLogEntry(models.Model):
return action return action
@classmethod @classmethod
def get_recorded_action(cls, user: User, comment: str = None): def get_recorded_action(cls, user, comment: str = None):
action = UserActionLogEntry.objects.create( action = UserActionLogEntry.objects.create(
user=user, user=user,
action=UserAction.RECORDED, action=UserAction.RECORDED,
@ -114,7 +110,7 @@ class UserActionLogEntry(models.Model):
return action return action
@classmethod @classmethod
def get_unrecorded_action(cls, user: User, comment: str = None): def get_unrecorded_action(cls, user, comment: str = None):
action = UserActionLogEntry.objects.create( action = UserActionLogEntry.objects.create(
user=user, user=user,
action=UserAction.UNRECORDED, action=UserAction.UNRECORDED,

View File

@ -1,6 +1,6 @@
from django.contrib import messages from django.contrib import messages
from django.contrib.auth.decorators import login_required 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.http import HttpRequest
from django.shortcuts import render, redirect, get_object_or_404 from django.shortcuts import render, redirect, get_object_or_404
from django.utils.translation import gettext_lazy as _ 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.contexts import BaseContext
from konova.decorators import any_group_check from konova.decorators import any_group_check
from user.forms import UserNotificationForm, UserContactForm from user.forms import UserNotificationForm, UserContactForm
from user.models import KonovaUserExtension
@login_required @login_required
@ -43,9 +42,6 @@ def notifications_view(request: HttpRequest):
""" """
template = "user/notifications.html" template = "user/notifications.html"
user = request.user user = request.user
konova_ext = KonovaUserExtension.objects.get_or_create(
user=user
)[0]
form = UserNotificationForm(user=user, data=request.POST or None) form = UserNotificationForm(user=user, data=request.POST or None)
if request.method == "POST": if request.method == "POST":
@ -65,7 +61,6 @@ def notifications_view(request: HttpRequest):
context = { context = {
"user": user, "user": user,
"form": form, "form": form,
"konova_ext": konova_ext,
} }
context = BaseContext(request, context).context context = BaseContext(request, context).context
return render(request, template, context) return render(request, template, context)