diff --git a/VRE/apps/study/models.py b/VRE/apps/study/models.py index f393e11..b29f8cf 100644 --- a/VRE/apps/study/models.py +++ b/VRE/apps/study/models.py @@ -161,7 +161,7 @@ class StudyRole(MetaDataModel): models.UniqueConstraint(fields=['study', 'researcher'], name='unique_researcher_study_role'), ] - def sent_invitation_email(self): + def sent_invitation_email(self, sender=None): # Generate JWT token jwt_data = { 'timestamp': int(self.invited_at.timestamp()), @@ -181,18 +181,25 @@ class StudyRole(MetaDataModel): } from_email = settings.EMAIL_FROM_ADDRESS - subject = render_to_string('invitation_email/subject.txt', template_variables) - html_message = render_to_string('invitation_email/body.html', template_variables) - text_message = render_to_string('invitation_email/body.txt', template_variables) + subject = render_to_string('email/invitation_to_study/subject.txt', template_variables) + html_message = render_to_string('email/invitation_to_study/body.html', template_variables) + text_message = render_to_string('email/invitation_to_study/body.txt', template_variables) if '' == text_message: text_message = remove_html_tags(html_message) + reply_to_headers = { + 'reply-to': f'{self.researcher.display_name}<{self.researcher.user.email}>' + } + + if sender is not None: + reply_to_headers['reply-to'] = f'{sender.display_name}<{sender.user.email}>' + message = EmailMultiRelated(subject, text_message, from_email, [f'{self.researcher.display_name}<{self.researcher.user.email}>'], - headers={'reply-to': self.researcher.user.email}) + headers=reply_to_headers) message.attach_alternative(html_message, 'text/html') @@ -224,6 +231,43 @@ class StudyRole(MetaDataModel): else: raise ValidationError(_('Unfortunately the token contains invalid data')) + def send_remove_notification_email(self, sender=None): + template_variables = { + 'researcher': self.researcher.display_name, + 'study': self.study.name, + 'sender': self.study.owner.display_name if sender is None else sender.display_name + } + + from_email = settings.EMAIL_FROM_ADDRESS + + subject = render_to_string('email/removed_from_study/subject.txt', template_variables) + html_message = render_to_string('email/removed_from_study/body.html', template_variables) + text_message = render_to_string('email/removed_from_study/body.txt', template_variables) + + if '' == text_message: + text_message = remove_html_tags(html_message) + + reply_to_headers = { + 'reply-to': f'{self.researcher.display_name}<{self.researcher.user.email}>' + } + + if sender is not None: + reply_to_headers['reply-to'] = f'{sender.display_name}<{sender.user.email}>' + + message = EmailMultiRelated(subject, + text_message, + from_email, + [f'{self.researcher.display_name}<{self.researcher.user.email}>'], + headers=reply_to_headers) + + message.attach_alternative(html_message, 'text/html') + + logo = Path(finders.find('images/RUG_Logo.jpg')) + if logo.is_file(): + message.attach_related_file(logo) + + return message.send() == 1 + def __str__(self): """str: Returns a readable string for the study role.""" - return f'{self.researcher} is {self.role} of {self.study.name}' + return f'{self.researcher.display_name} is {self.role} of {self.study.name}' diff --git a/VRE/apps/study/templates/invitation_email/body.html b/VRE/apps/study/templates/email/invitation_to_study/body.html similarity index 100% rename from VRE/apps/study/templates/invitation_email/body.html rename to VRE/apps/study/templates/email/invitation_to_study/body.html diff --git a/VRE/apps/study/templates/invitation_email/body.txt b/VRE/apps/study/templates/email/invitation_to_study/body.txt similarity index 100% rename from VRE/apps/study/templates/invitation_email/body.txt rename to VRE/apps/study/templates/email/invitation_to_study/body.txt diff --git a/VRE/apps/study/templates/invitation_email/subject.txt b/VRE/apps/study/templates/email/invitation_to_study/subject.txt similarity index 100% rename from VRE/apps/study/templates/invitation_email/subject.txt rename to VRE/apps/study/templates/email/invitation_to_study/subject.txt diff --git a/VRE/apps/study/templates/email/removed_from_study/body.html b/VRE/apps/study/templates/email/removed_from_study/body.html new file mode 100644 index 0000000..78a5619 --- /dev/null +++ b/VRE/apps/study/templates/email/removed_from_study/body.html @@ -0,0 +1,4 @@ +RUG Logo +

Dear {{researcher}},

+

Hereby we inform you that you have been removed from the study {{study}}.

+

Kind regards,
{{sender}}

\ No newline at end of file diff --git a/VRE/apps/study/templates/email/removed_from_study/body.txt b/VRE/apps/study/templates/email/removed_from_study/body.txt new file mode 100644 index 0000000..417b575 --- /dev/null +++ b/VRE/apps/study/templates/email/removed_from_study/body.txt @@ -0,0 +1,6 @@ +Dear {{researcher}}, + +Hereby we inform you that you have been removed from the study {{study}}. + +Kind regards, +{{sender}} \ No newline at end of file diff --git a/VRE/apps/study/templates/email/removed_from_study/subject.txt b/VRE/apps/study/templates/email/removed_from_study/subject.txt new file mode 100644 index 0000000..4fb54bc --- /dev/null +++ b/VRE/apps/study/templates/email/removed_from_study/subject.txt @@ -0,0 +1 @@ +Dear {{researcher}} you are removed from the study {{study}} \ No newline at end of file diff --git a/VRE/apps/study/views.py b/VRE/apps/study/views.py index 997261c..02f1713 100644 --- a/VRE/apps/study/views.py +++ b/VRE/apps/study/views.py @@ -265,6 +265,9 @@ class Contributors(ModelViewSet): if contributor.study.contributors.filter(studyrole__role=StudyRoleNames.ADMIN).exclude(studyrole__researcher=contributor.researcher).count() == 0: raise ValidationError(_('At least 1 administrator needs to remain for this study')) + # Send an email to the researcher that is removed from the study + contributor.send_remove_notification_email(sender=self.request.user.researcher) + self.perform_destroy(contributor) return Response(status=status.HTTP_204_NO_CONTENT) @@ -284,7 +287,7 @@ def process_study_invite(request, *args, **kwargs): invite = InviteSerializer(data=request.data) invite.is_valid(raise_exception=True) contributor = invite.save(study=study) - contributor.sent_invitation_email() + contributor.sent_invitation_email(sender=request.user.researcher) return Response({'message': _('Invitation to %(researcher_name)s for study %(study_name)s is sent.') % {'researcher_name': contributor.researcher.display_name, 'study_name': study.name}})