From 963854652ef9d6df09be8eeedfde9b07be7b9259 Mon Sep 17 00:00:00 2001 From: mpeltriaux Date: Fri, 18 Feb 2022 15:19:37 +0100 Subject: [PATCH] #101 Team mails * adds mail templates for shared data actions * fixes bug where deleted compensations would be used for checking --- intervention/forms/modalForms.py | 6 +- konova/models/object.py | 87 ++++++++--- konova/tasks.py | 42 ++++++ konova/utils/mailer.py | 138 ++++++++++++++++++ locale/de/LC_MESSAGES/django.mo | Bin 39892 -> 40282 bytes locale/de/LC_MESSAGES/django.po | 43 +++++- .../checking/shared_data_checked_team.html | 28 ++++ .../deleting/shared_data_deleted_team.html | 28 ++++ .../recording/shared_data_recorded_team.html | 33 +++++ .../shared_data_unrecorded_team.html | 33 +++++ .../sharing/shared_access_given_team.html | 34 +++++ .../sharing/shared_access_removed_team.html | 29 ++++ user/models/team.py | 79 ++++++++++ 13 files changed, 551 insertions(+), 29 deletions(-) create mode 100644 templates/email/checking/shared_data_checked_team.html create mode 100644 templates/email/deleting/shared_data_deleted_team.html create mode 100644 templates/email/recording/shared_data_recorded_team.html create mode 100644 templates/email/recording/shared_data_unrecorded_team.html create mode 100644 templates/email/sharing/shared_access_given_team.html create mode 100644 templates/email/sharing/shared_access_removed_team.html diff --git a/intervention/forms/modalForms.py b/intervention/forms/modalForms.py index 3947938..1e5febf 100644 --- a/intervention/forms/modalForms.py +++ b/intervention/forms/modalForms.py @@ -141,7 +141,7 @@ class ShareModalForm(BaseModalForm): self.load_initial_data(form_data) def save(self): - self.instance.update_sharing_user(self) + self.instance.update_shared_access(self) class NewRevocationModalForm(BaseModalForm): @@ -290,7 +290,9 @@ class CheckModalForm(BaseModalForm): Returns: """ - comps = self.instance.compensations.all() + comps = self.instance.compensations.filter( + deleted=None, + ) comps_valid = True for comp in comps: checker = comp.quality_check() diff --git a/konova/models/object.py b/konova/models/object.py index 92b3cca..f224b68 100644 --- a/konova/models/object.py +++ b/konova/models/object.py @@ -15,7 +15,10 @@ from django.db.models import QuerySet from konova.sub_settings.lanis_settings import DEFAULT_SRID_RLP, LANIS_ZOOM_LUT, LANIS_LINK_TEMPLATE 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 + celery_send_mail_shared_data_deleted, celery_send_mail_shared_data_checked, \ + celery_send_mail_shared_access_given_team, celery_send_mail_shared_access_removed_team, \ + celery_send_mail_shared_data_checked_team, celery_send_mail_shared_data_deleted_team, \ + celery_send_mail_shared_data_unrecorded_team, celery_send_mail_shared_data_recorded_team from django.core.exceptions import ObjectDoesNotExist from django.http import HttpRequest from django.utils.timezone import now @@ -130,6 +133,11 @@ class BaseObject(BaseResource): for user_id in shared_users: celery_send_mail_shared_data_deleted.delay(self.identifier, self.title, user_id) + # Send mail + shared_teams = self.shared_teams.values_list("id", flat=True) + for team_id in shared_teams: + celery_send_mail_shared_data_deleted_team.delay(self.identifier, self.title, team_id) + self.save() def mark_as_edited(self, performing_user, request: HttpRequest = None, edit_comment: str = None): @@ -258,10 +266,15 @@ class RecordableObjectMixin(models.Model): self.save() self.log.add(action) - shared_users = self.users.all().values_list("id", flat=True) + shared_users = self.shared_users.values_list("id", flat=True) + shared_teams = self.shared_teams.values_list("id", flat=True) + for user_id in shared_users: celery_send_mail_shared_data_unrecorded.delay(self.identifier, self.title, user_id) + for team_id in shared_teams: + celery_send_mail_shared_data_unrecorded_team.delay(self.identifier, self.title, team_id) + return action def set_recorded(self, user): @@ -281,10 +294,15 @@ class RecordableObjectMixin(models.Model): self.save() self.log.add(action) - shared_users = self.users.all().values_list("id", flat=True) + shared_users = self.shared_users.values_list("id", flat=True) + shared_teams = self.shared_teams.values_list("id", flat=True) + for user_id in shared_users: celery_send_mail_shared_data_recorded.delay(self.identifier, self.title, user_id) + for team_id in shared_teams: + celery_send_mail_shared_data_recorded_team.delay(self.identifier, self.title, team_id) + return action def unrecord(self, performing_user, request: HttpRequest = None): @@ -367,10 +385,15 @@ class CheckableObjectMixin(models.Model): self.save() # Send mail - shared_users = self.users.all().values_list("id", flat=True) + shared_users = self.shared_users.values_list("id", flat=True) for user_id in shared_users: celery_send_mail_shared_data_checked.delay(self.identifier, self.title, user_id) + # Send mail + shared_teams = self.shared_teams.values_list("id", flat=True) + for team_id in shared_teams: + celery_send_mail_shared_data_checked_team.delay(self.identifier, self.title, team_id) + self.log.add(action) return action @@ -488,8 +511,8 @@ class ShareableObjectMixin(models.Model): """ self.users.set(user_list) - def update_sharing_user(self, form): - """ Adds a new user with shared access to the object + def _update_shared_teams(self, form): + """ Updates shared access on the object for teams Args: form (ShareModalForm): The form holding the data @@ -497,33 +520,46 @@ class ShareableObjectMixin(models.Model): Returns: """ - from user.models import User form_data = form.cleaned_data + shared_teams = self.shared_teams # Fetch selected teams and find out which user IDs are in removed teams -> mails need to be sent accessing_teams = form_data["teams"] - removed_team_users = self.teams.all().exclude( + removed_teams = shared_teams.exclude( id__in=accessing_teams - ).values_list("users__id", flat=True) - accessing_team_users = User.objects.filter( - id__in=accessing_teams.values_list("users", flat=True) - ) - new_team_users = accessing_team_users.exclude( - id__in=self.shared_users ).values_list("id", flat=True) + new_teams = accessing_teams.exclude( + id__in=shared_teams + ).values_list("id", flat=True) + + for team_id in new_teams: + celery_send_mail_shared_access_given_team.delay(self.identifier, self.title, team_id) + for team_id in removed_teams: + celery_send_mail_shared_access_removed_team.delay(self.identifier, self.title, team_id) + + self.share_with_team_list(accessing_teams) + + def _update_shared_users(self, form): + """ Updates shared access on the object for single users + + Args: + form (ShareModalForm): The form holding the data + + Returns: + + """ + form_data = form.cleaned_data + shared_users = self.shared_users # Fetch selected users accessing_users = form_data["users"] - removed_users = self.users.all().exclude( + removed_users = shared_users.exclude( id__in=accessing_users ).values_list("id", flat=True) new_users = accessing_users.exclude( - id__in=self.shared_users + id__in=shared_users ).values_list("id", flat=True) - new_users = new_users.union(new_team_users) - removed_users = removed_users.union(removed_team_users) - # Send mails for user_id in removed_users: celery_send_mail_shared_access_removed.delay(self.identifier, self.title, user_id) @@ -532,7 +568,18 @@ class ShareableObjectMixin(models.Model): # Set new shared users self.share_with_user_list(accessing_users) - self.share_with_team_list(accessing_teams) + + def update_shared_access(self, form): + """ Updates shared access on the object + + Args: + form (ShareModalForm): The form holding the data + + Returns: + + """ + self._update_shared_teams(form) + self._update_shared_users(form) @property def shared_users(self) -> QuerySet: diff --git a/konova/tasks.py b/konova/tasks.py index c74a2bd..798effb 100644 --- a/konova/tasks.py +++ b/konova/tasks.py @@ -38,6 +38,20 @@ def celery_send_mail_shared_access_given(obj_identifier, obj_title=None, user_id user.send_mail_shared_access_given(obj_identifier, obj_title) +@shared_task +def celery_send_mail_shared_access_removed_team(obj_identifier, obj_title=None, team_id=None): + from user.models import Team + team = Team.objects.get(id=team_id) + team.send_mail_shared_access_removed(obj_identifier, obj_title) + + +@shared_task +def celery_send_mail_shared_access_given_team(obj_identifier, obj_title=None, team_id=None): + from user.models import Team + team = Team.objects.get(id=team_id) + team.send_mail_shared_access_given_team(obj_identifier, obj_title) + + @shared_task def celery_send_mail_shared_data_recorded(obj_identifier, obj_title=None, user_id=None): from user.models import User @@ -52,6 +66,20 @@ def celery_send_mail_shared_data_unrecorded(obj_identifier, obj_title=None, user user.send_mail_shared_data_unrecorded(obj_identifier, obj_title) +@shared_task +def celery_send_mail_shared_data_recorded_team(obj_identifier, obj_title=None, team_id=None): + from user.models import Team + team = Team.objects.get(id=team_id) + team.send_mail_shared_data_recorded(obj_identifier, obj_title) + + +@shared_task +def celery_send_mail_shared_data_unrecorded_team(obj_identifier, obj_title=None, team_id=None): + from user.models import Team + team = Team.objects.get(id=team_id) + team.send_mail_shared_data_unrecorded(obj_identifier, obj_title) + + @shared_task def celery_send_mail_shared_data_deleted(obj_identifier, obj_title=None, user_id=None): from user.models import User @@ -64,3 +92,17 @@ def celery_send_mail_shared_data_checked(obj_identifier, obj_title=None, user_id from user.models import User user = User.objects.get(id=user_id) user.send_mail_shared_data_checked(obj_identifier, obj_title) + + +@shared_task +def celery_send_mail_shared_data_deleted_team(obj_identifier, obj_title=None, team_id=None): + from user.models import Team + team = Team.objects.get(id=team_id) + team.send_mail_shared_data_deleted(obj_identifier, obj_title) + + +@shared_task +def celery_send_mail_shared_data_checked_team(obj_identifier, obj_title=None, team_id=None): + from user.models import Team + team = Team.objects.get(id=team_id) + team.send_mail_shared_data_checked(obj_identifier, obj_title) diff --git a/konova/utils/mailer.py b/konova/utils/mailer.py index 33907f3..dd8eef1 100644 --- a/konova/utils/mailer.py +++ b/konova/utils/mailer.py @@ -92,6 +92,144 @@ class Mailer: msg ) + def send_mail_shared_access_given_team(self, obj_identifier, obj_title, team): + """ Send a mail if a team just got access to the object + + Args: + obj_identifier (str): The object identifier + + Returns: + + """ + context = { + "team": team, + "obj_identifier": obj_identifier, + "obj_title": obj_title, + "EMAIL_REPLY_TO": EMAIL_REPLY_TO, + } + msg = render_to_string("email/sharing/shared_access_given_team.html", context) + user_mail_address = team.users.values_list("email", flat=True) + self.send( + user_mail_address, + _("{} - Shared access given").format(obj_identifier), + msg + ) + + def send_mail_shared_access_removed_team(self, obj_identifier, obj_title, team): + """ Send a mail if a team just lost access to the object + + Args: + obj_identifier (str): The object identifier + + Returns: + + """ + context = { + "team": team, + "obj_identifier": obj_identifier, + "obj_title": obj_title, + "EMAIL_REPLY_TO": EMAIL_REPLY_TO, + } + msg = render_to_string("email/sharing/shared_access_removed_team.html", context) + user_mail_address = team.users.values_list("email", flat=True) + self.send( + user_mail_address, + _("{} - Shared access removed").format(obj_identifier), + msg + ) + + def send_mail_shared_data_unrecorded_team(self, obj_identifier, obj_title, team): + """ Send a mail if data has just been unrecorded + + Args: + obj_identifier (str): The object identifier + + Returns: + + """ + context = { + "team": team, + "obj_identifier": obj_identifier, + "obj_title": obj_title, + "EMAIL_REPLY_TO": EMAIL_REPLY_TO, + } + msg = render_to_string("email/recording/shared_data_unrecorded_team.html", context) + user_mail_address = team.users.values_list("email", flat=True) + self.send( + user_mail_address, + _("{} - Shared data unrecorded").format(obj_identifier), + msg + ) + + def send_mail_shared_data_recorded_team(self, obj_identifier, obj_title, team): + """ Send a mail if data has just been recorded + + Args: + obj_identifier (str): The object identifier + + Returns: + + """ + context = { + "team": team, + "obj_identifier": obj_identifier, + "obj_title": obj_title, + "EMAIL_REPLY_TO": EMAIL_REPLY_TO, + } + msg = render_to_string("email/recording/shared_data_recorded_team.html", context) + user_mail_address = team.users.values_list("email", flat=True) + self.send( + user_mail_address, + _("{} - Shared data recorded").format(obj_identifier), + msg + ) + + def send_mail_shared_data_checked_team(self, obj_identifier, obj_title, team): + """ Send a mail if data has just been checked + + Args: + obj_identifier (str): The object identifier + + Returns: + + """ + context = { + "team": team, + "obj_identifier": obj_identifier, + "obj_title": obj_title, + "EMAIL_REPLY_TO": EMAIL_REPLY_TO, + } + msg = render_to_string("email/checking/shared_data_checked_team.html", context) + user_mail_address = team.users.values_list("email", flat=True) + self.send( + user_mail_address, + _("{} - Shared data checked").format(obj_identifier), + msg + ) + + def send_mail_shared_data_deleted_team(self, obj_identifier, obj_title, team): + """ Send a mail if data has just been deleted + + Args: + obj_identifier (str): The object identifier + + Returns: + + """ + context = { + "team": team, + "obj_identifier": obj_identifier, + "obj_title": obj_title, + "EMAIL_REPLY_TO": EMAIL_REPLY_TO, + } + msg = render_to_string("email/deleting/shared_data_deleted_team.html", context) + user_mail_address = team.users.values_list("email", flat=True) + self.send( + user_mail_address, + _("{} - Shared data deleted").format(obj_identifier), + msg + ) + def send_mail_shared_data_recorded(self, obj_identifier, obj_title, user): """ Send a mail if the user's shared data has just been unrecorded diff --git a/locale/de/LC_MESSAGES/django.mo b/locale/de/LC_MESSAGES/django.mo index ced4ab1ce70235e9c2f809480b12816984ba7a18..9437cb993a50c84e2c397c3f30f0e5d7cf7ba041 100644 GIT binary patch delta 11524 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 Zr47vWROJ^Gobsp8FUQ;wwRDTue*k7fY3cv~ delta 11374 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 Its3a{e>B)xF#rGn diff --git a/locale/de/LC_MESSAGES/django.po b/locale/de/LC_MESSAGES/django.po index 94efbd7..051894c 100644 --- a/locale/de/LC_MESSAGES/django.po +++ b/locale/de/LC_MESSAGES/django.po @@ -26,7 +26,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-02-18 14:01+0100\n" +"POT-Creation-Date: 2022-02-18 14:50+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -1796,27 +1796,27 @@ msgstr "In Zwischenablage kopiert" msgid "{} - Shared access removed" msgstr "{} - Zugriff entzogen" -#: konova/utils/mailer.py:91 +#: konova/utils/mailer.py:91 konova/utils/mailer.py:114 msgid "{} - Shared access given" msgstr "{} - Zugriff freigegeben" -#: konova/utils/mailer.py:114 +#: konova/utils/mailer.py:137 msgid "{} - Shared data recorded" msgstr "{} - Freigegebene Daten verzeichnet" -#: konova/utils/mailer.py:137 +#: konova/utils/mailer.py:160 msgid "{} - Shared data unrecorded" msgstr "{} - Freigegebene Daten entzeichnet" -#: konova/utils/mailer.py:160 +#: konova/utils/mailer.py:183 msgid "{} - Shared data deleted" msgstr "{} - Freigegebene Daten gelöscht" -#: konova/utils/mailer.py:183 +#: konova/utils/mailer.py:206 msgid "{} - Shared data checked" msgstr "{} - Freigegebene Daten geprüft" -#: konova/utils/mailer.py:204 templates/email/api/verify_token.html:4 +#: konova/utils/mailer.py:227 templates/email/api/verify_token.html:4 msgid "Request for new API token" msgstr "Anfrage für neuen API Token" @@ -2092,7 +2092,9 @@ msgstr "" #: templates/email/recording/shared_data_recorded.html:19 #: templates/email/recording/shared_data_unrecorded.html:19 #: templates/email/sharing/shared_access_given.html:20 +#: templates/email/sharing/shared_access_given_team.html:20 #: templates/email/sharing/shared_access_removed.html:20 +#: templates/email/sharing/shared_access_removed_team.html:20 msgid "Best regards" msgstr "Beste Grüße" @@ -2179,6 +2181,7 @@ msgstr "" "zugehörigen Kompensationen automatisch entzeichnet worden sind." #: templates/email/sharing/shared_access_given.html:4 +#: templates/email/sharing/shared_access_given_team.html:4 msgid "Access shared" msgstr "Zugriff freigegeben" @@ -2187,10 +2190,12 @@ 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:16 +#: templates/email/sharing/shared_access_given_team.html:16 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:17 +#: templates/email/sharing/shared_access_given_team.html:17 msgid "" "The shared dataset appears now by default on your overview for this dataset " "type." @@ -2199,6 +2204,7 @@ msgstr "" "Datensatztyp im KSP gelistet." #: templates/email/sharing/shared_access_given.html:27 +#: templates/email/sharing/shared_access_given_team.html:27 msgid "" "Please note: Shared access on an intervention means you automatically have " "editing access to related compensations." @@ -2207,7 +2213,17 @@ msgstr "" "Sie automatisch auch Zugriff auf die zugehörigen Kompensationen erhalten " "haben." +#: templates/email/sharing/shared_access_given_team.html:8 +#: templates/email/sharing/shared_access_removed_team.html:8 +msgid "Hello team" +msgstr "Hallo Team" + +#: templates/email/sharing/shared_access_given_team.html:10 +msgid "the following dataset has just been shared with your team" +msgstr "der folgende Datensatz wurde soeben für Ihr Team freigegeben " + #: templates/email/sharing/shared_access_removed.html:4 +#: templates/email/sharing/shared_access_removed_team.html:4 msgid "Shared access removed" msgstr "Freigegebener Zugriff entzogen" @@ -2219,10 +2235,12 @@ msgstr "" "entzogen: " #: templates/email/sharing/shared_access_removed.html:16 +#: templates/email/sharing/shared_access_removed_team.html:16 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:17 +#: templates/email/sharing/shared_access_removed_team.html:17 msgid "" "Please use the provided search filter on the dataset`s overview pages to " "find them." @@ -2230,6 +2248,14 @@ msgstr "" "Nutzen Sie hierzu einfach die entsprechenden Suchfilter auf den " "Übersichtsseiten" +#: templates/email/sharing/shared_access_removed_team.html:10 +msgid "" +"your teams shared access, including editing, has been revoked for the " +"dataset " +msgstr "" +"Ihrem Team wurde soeben der bearbeitende Zugriff auf den folgenden Datensatz " +"entzogen: " + #: templates/email/signature.html:6 msgid "Please do not reply on this mail." msgstr "Bitte antworten Sie nicht auf diese Mail." @@ -4118,6 +4144,9 @@ msgstr "" msgid "Unable to connect to qpid with SASL mechanism %s" msgstr "" +#~ msgid "your teams" +#~ msgstr "Team entfernen" + #~ msgid "Remove check to remove access for this user" #~ msgstr "Wählen Sie die Nutzer ab, die keinen Zugriff mehr haben sollen" diff --git a/templates/email/checking/shared_data_checked_team.html b/templates/email/checking/shared_data_checked_team.html new file mode 100644 index 0000000..ee81381 --- /dev/null +++ b/templates/email/checking/shared_data_checked_team.html @@ -0,0 +1,28 @@ +{% load i18n %} + +
+

{% trans 'Shared data checked' %}

+

{{obj_identifier}}

+
+
+ {% trans 'Hello team' %} {{team.name}}, +
+ {% trans 'the following dataset has just been checked' %} +
+ {{obj_identifier}} +
+ {{obj_title}} +
+ {% 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_team.html b/templates/email/deleting/shared_data_deleted_team.html new file mode 100644 index 0000000..cedb2a4 --- /dev/null +++ b/templates/email/deleting/shared_data_deleted_team.html @@ -0,0 +1,28 @@ +{% load i18n %} + +
+

{% trans 'Shared data deleted' %}

+

{{obj_identifier}}

+
+
+ {% trans 'Hello team' %} {{team.name}}, +
+ {% trans 'the following dataset has just been deleted' %} +
+ {{obj_identifier}} +
+ "{{obj_title}}" +
+ {% 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_team.html b/templates/email/recording/shared_data_recorded_team.html new file mode 100644 index 0000000..12efa8f --- /dev/null +++ b/templates/email/recording/shared_data_recorded_team.html @@ -0,0 +1,33 @@ +{% load i18n %} + +
+

{% trans 'Shared data recorded' %}

+

{{obj_identifier}}

+
+
+ {% trans 'Hello team' %} {{team.name}}, +
+ {% trans 'the following dataset has just been recorded' %} +
+ {{obj_identifier}} +
+ "{{obj_title}}" +
+ {% 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_team.html b/templates/email/recording/shared_data_unrecorded_team.html new file mode 100644 index 0000000..6414155 --- /dev/null +++ b/templates/email/recording/shared_data_unrecorded_team.html @@ -0,0 +1,33 @@ +{% load i18n %} + +
+

{% trans 'Shared data unrecorded' %}

+

{{obj_identifier}}

+
+
+ {% trans 'Hello team' %} {{team.name}}, +
+ {% trans 'the following dataset has just been unrecorded' %} +
+ {{obj_identifier}} +
+ "{{obj_title}}" +
+ {% 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_team.html b/templates/email/sharing/shared_access_given_team.html new file mode 100644 index 0000000..990ba2d --- /dev/null +++ b/templates/email/sharing/shared_access_given_team.html @@ -0,0 +1,34 @@ +{% load i18n %} + +
+

{% trans 'Access shared' %}

+

{{obj_identifier}}

+
+
+ {% trans 'Hello team' %} {{team.name}}, +
+ {% trans 'the following dataset has just been shared with your team' %} +
+ {{obj_identifier}} +
+ "{{obj_title}}" +
+ {% 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_team.html b/templates/email/sharing/shared_access_removed_team.html new file mode 100644 index 0000000..5472ef7 --- /dev/null +++ b/templates/email/sharing/shared_access_removed_team.html @@ -0,0 +1,29 @@ +{% load i18n %} + +
+

{% trans 'Shared access removed' %}

+

{{obj_identifier}}

+
+
+ {% trans 'Hello team' %} {{team.name}}, +
+ {% trans 'your teams shared access, including editing, has been revoked for the dataset ' %} +
+ {{obj_identifier}} +
+ "{{obj_title}}" +
+ {% 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/user/models/team.py b/user/models/team.py index c26af3c..e36c95b 100644 --- a/user/models/team.py +++ b/user/models/team.py @@ -1,6 +1,7 @@ from django.db import models from konova.models import UuidModel +from konova.utils.mailer import Mailer class Team(UuidModel): @@ -14,3 +15,81 @@ class Team(UuidModel): def __str__(self): return self.name + + def send_mail_shared_access_given_team(self, obj_identifier, obj_title): + """ Sends a mail to the team members in case of given shared access + + Args: + obj_identifier (): + obj_title (): + + Returns: + + """ + mailer = Mailer() + mailer.send_mail_shared_access_given_team(obj_identifier, obj_title, self) + + def send_mail_shared_access_removed(self, obj_identifier, obj_title): + """ Sends a mail to the team members in case of removed shared access + + Args: + obj_identifier (): + obj_title (): + + Returns: + + """ + mailer = Mailer() + mailer.send_mail_shared_access_removed_team(obj_identifier, obj_title, self) + + def send_mail_shared_data_unrecorded(self, obj_identifier, obj_title): + """ Sends a mail to the team members in case of unrecorded data + + Args: + obj_identifier (): + obj_title (): + + Returns: + + """ + mailer = Mailer() + mailer.send_mail_shared_data_unrecorded_team(obj_identifier, obj_title, self) + + def send_mail_shared_data_recorded(self, obj_identifier, obj_title): + """ Sends a mail to the team members in case of unrecorded data + + Args: + obj_identifier (): + obj_title (): + + Returns: + + """ + mailer = Mailer() + mailer.send_mail_shared_data_recorded_team(obj_identifier, obj_title, self) + + def send_mail_shared_data_checked(self, obj_identifier, obj_title): + """ Sends a mail to the team members in case of checked data + + Args: + obj_identifier (): + obj_title (): + + Returns: + + """ + mailer = Mailer() + mailer.send_mail_shared_data_checked_team(obj_identifier, obj_title, self) + + def send_mail_shared_data_deleted(self, obj_identifier, obj_title): + """ Sends a mail to the team members in case of deleted data + + Args: + obj_identifier (): + obj_title (): + + Returns: + + """ + mailer = Mailer() + mailer.send_mail_shared_data_deleted_team(obj_identifier, obj_title, self)