Repository: e-valuation/EvaP

Issue:
there is no option to send a mail to the responsible person
/fsr/semester/x/course/y/email currently does not allow to send a mail only to the responsible person (and his delegates), this should be changed. In addition the page could be improved design-wise.

there is no option to send a mail to the responsible person
/fsr/semester/x/course/y/email currently does not allow to send a mail only to the responsible person (and his delegates), this should be changed. In addition the page could be improved design-wise.



Discussion:

Resolving patch:
diff --git a/evap/evaluation/models.py b/evap/evaluation/models.py
--- a/evap/evaluation/models.py
+++ b/evap/evaluation/models.py
@@ -288,6 +288,9 @@ def is_user_responsible_or_delegate(self, user):
     def is_user_contributor(self, user):
         return self.contributions.filter(contributor=user).exists()
 
+    def is_user_editor(self, user):
+        return self.contributions.filter(contributor=user, can_edit=True).exists()
+
     def warnings(self):
         result = []
         if self.state == 'new' and not self.has_enough_questionnaires():
@@ -624,17 +627,20 @@ def get_login_key_template(cls):
         return cls.objects.get(name="Login Key Created")
 
     @classmethod
-    def recipient_list_for_course(cls, course, send_to_editors, send_to_contributors, send_to_due_participants, send_to_all_participants):
+    def recipient_list_for_course(cls, course, send_to):
         recipients = []
 
-        if send_to_contributors:
+        if send_to["responsible"]:
+            recipients += [course.responsible_contributor]
+
+        if send_to["contributors"]:
             recipients += [c.contributor for c in course.contributions.exclude(contributor=None)]
-        elif send_to_editors:
+        elif send_to["editors"]:
             recipients += [c.contributor for c in course.contributions.exclude(contributor=None).filter(can_edit=True)]
 
-        if send_to_all_participants:
+        if send_to["all_participants"]:
             recipients += course.participants.all()
-        elif send_to_due_participants:
+        elif send_to["due_participants"]:
             recipients += course.due_participants
 
         return recipients
@@ -643,17 +649,17 @@ def recipient_list_for_course(cls, course, send_to_editors, send_to_contributors
     def render_string(cls, text, dictionary):
         return Template(text).render(Context(dictionary, autoescape=False))
 
-    def send_to_users_in_courses(self, courses, send_to_editors=False, send_to_contributors=False, send_to_due_participants=False, send_to_all_participants=False):
+    def send_to_users_in_courses(self, courses, send_to):
         user_course_map = {}
         for course in courses:
             responsible = UserProfile.get_for_user(course.responsible_contributor)
-            for user in self.recipient_list_for_course(course, send_to_editors, send_to_contributors, send_to_due_participants, send_to_all_participants):
+            for user in self.recipient_list_for_course(course, send_to):
                 if user.email and user not in responsible.cc_users.all() and user not in responsible.delegates.all():
                     user_course_map.setdefault(user, []).append(course)
 
         for user, courses in user_course_map.iteritems():
             cc_users = []
-            if send_to_editors and any(course.contributions.filter(can_edit=True, contributor=user).exists() for course in courses):
+            if (send_to["responsible"] or send_to["editors"]) and any(course.is_user_editor(user) for course in courses):
                 cc_users += UserProfile.get_for_user(user).delegates.all()
             cc_users += UserProfile.get_for_user(user).cc_users.all()
             cc_addresses = [p.email for p in cc_users if p.email]
diff --git a/evap/fsr/forms.py b/evap/fsr/forms.py
--- a/evap/fsr/forms.py
+++ b/evap/fsr/forms.py
@@ -110,6 +110,7 @@ def validate_unique(self):
 class CourseEmailForm(forms.Form, BootstrapMixin):
     sendToDueParticipants = forms.BooleanField(label=_("Send to participants who didn't vote yet"), required=False, initial=True)
     sendToAllParticipants = forms.BooleanField(label=_("Send to all participants"), required=False)
+    sendToResponsible = forms.BooleanField(label=_("Send to the responsible person"), required=False)
     sendToEditors = forms.BooleanField(label=_("Send to editors"), required=False)
     sendToContributors = forms.BooleanField(label=_("Send to all contributors (includes editors)"), required=False)
     subject = forms.CharField(label=_("Subject"))
@@ -120,13 +121,19 @@ def __init__(self, *args, **kwargs):
         self.template = EmailTemplate()
         super(CourseEmailForm, self).__init__(*args, **kwargs)
 
-    def clean(self):
-        cleaned_data = self.cleaned_data
 
-        if not (cleaned_data.get('sendToDueParticipants') or cleaned_data.get('sendToAllParticipants') or cleaned_data.get('sendToEditors') or cleaned_data.get('sendToContributors')):
+    def clean(self):
+        self.recipient_groups = {
+            'all_participants': self.cleaned_data.get('sendToAllParticipants'),
+            'due_participants': self.cleaned_data.get('sendToDueParticipants'),
+            'responsible': self.cleaned_data.get('sendToResponsible'),
+            'editors': self.cleaned_data.get('sendToEditors'),
+            'contributors': self.cleaned_data.get('sendToContributors') }
+
+        if len(self.recipient_groups) == 0:
             raise forms.ValidationError(_(u"No recipient selected. Choose at least one group of recipients."))
 
-        return cleaned_data
+        return self.cleaned_data
 
     # returns whether all recepients have an email address
     def all_recepients_reachable(self):
@@ -134,12 +141,13 @@ def all_recepients_reachable(self):
 
     # returns the number of recepients without an email address
     def missing_email_addresses(self):
-        return len([user for user in self.template.recipient_list_for_course(self.instance, self.cleaned_data.get('sendToEditors'), self.cleaned_data.get('sendToContributors'), self.cleaned_data.get('sendToDueParticipants'), self.cleaned_data.get('sendToAllParticipants')) if not user.email])
+        recipients = self.template.recipient_list_for_course(self.instance, self.recipient_groups)
+        return len([user for user in recipients if not user.email]) > 0
 
     def send(self):
         self.template.subject = self.cleaned_data.get('subject')
         self.template.body = self.cleaned_data.get('body')
-        self.template.send_to_users_in_courses([self.instance], send_to_editors=self.cleaned_data.get('sendToEditors'), send_to_contributors=self.cleaned_data.get('sendToContributors'), send_to_due_participants=self.cleaned_data.get('sendToDueParticipants'), send_to_all_participants=self.cleaned_data.get('sendToAllParticipants'))
+        self.template.send_to_users_in_courses([self.instance], self.recipient_groups)
 
 class QuestionnaireForm(forms.ModelForm, BootstrapMixin):
     class Meta:


Test patch: