Repository: e-valuation/EvaP

Issue:
Possibility to change evaluation period during or after evaluation
It should be possible to re-open evaluations after the end of the evaluation period.

Likewise, it should be possible to change the period when the course is in evaluation.



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
@@ -194,10 +194,14 @@ def is_fully_checked_except(self, ignored_answers):
         """Shortcut for finding out if all text answers to this course have been checked except for specified answers"""
         return not self.open_textanswer_set.exclude(pk__in=ignored_answers).exists()
 
+    def is_in_evaluation_period(self):
+        today = datetime.date.today()
+        return today >= self.vote_start_date and today <= self.vote_end_date
+
     def can_user_vote(self, user):
         """Returns whether the user is allowed to vote on this course."""
         return (self.state == "inEvaluation"
-            and datetime.date.today() <= self.vote_end_date
+            and self.is_in_evaluation_period
             and user in self.participants.all()
             and user not in self.voters.all())
 
@@ -210,7 +214,7 @@ def can_user_see_results(self, user):
 
     @property
     def can_staff_edit(self):
-        return not self.is_archived and self.state in ['new', 'prepared', 'lecturerApproved', 'approved', 'inEvaluation']
+        return not self.is_archived and self.state in ['new', 'prepared', 'lecturerApproved', 'approved', 'inEvaluation', 'evaluated', 'reviewed']
 
     @property
     def can_staff_delete(self):
@@ -244,10 +248,14 @@ def staff_approve(self):
     def revert_to_new(self):
         pass
 
-    @transition(field=state, source='approved', target='inEvaluation')
+    @transition(field=state, source='approved', target='inEvaluation', conditions=[is_in_evaluation_period])
     def evaluation_begin(self):
         pass
 
+    @transition(field=state, source=['evaluated', 'reviewed'], target='inEvaluation', conditions=[is_in_evaluation_period])
+    def reopen_evaluation(self):
+        pass
+
     @transition(field=state, source='inEvaluation', target='evaluated')
     def evaluation_end(self):
         pass
diff --git a/evap/staff/forms.py b/evap/staff/forms.py
--- a/evap/staff/forms.py
+++ b/evap/staff/forms.py
@@ -11,6 +11,8 @@
 from evap.staff.fields import ToolTipModelMultipleChoiceField
 from evap.staff.tools import EMAIL_RECIPIENTS
 
+import datetime
+
 
 class ImportForm(forms.Form, BootstrapMixin):
     vote_start_date = forms.DateField(label=_("First date to vote"), localize=True)
@@ -60,9 +62,13 @@ def __init__(self, *args, **kwargs):
             self.fields['last_modified_user_2'].initial = self.instance.last_modified_user.full_name
         self.fields['last_modified_user_2'].widget.attrs['readonly'] = "True"
 
-        if self.instance.state == "inEvaluation":
+        if self.instance.state in ['inEvaluation', 'evaluated', 'reviewed']:
             self.fields['vote_start_date'].widget.attrs['readonly'] = "True"
-            self.fields['vote_end_date'].widget.attrs['readonly'] = "True"
+
+    def clean(self):
+        vote_end_date = self.cleaned_data.get('vote_end_date')
+        if vote_end_date and vote_end_date < datetime.date.today():
+            raise forms.ValidationError(_("The vote end date must be in the future."))
 
     def save(self, *args, **kw):
         user = kw.pop("user")
diff --git a/evap/staff/views.py b/evap/staff/views.py
--- a/evap/staff/views.py
+++ b/evap/staff/views.py
@@ -355,6 +355,8 @@ def course_edit(request, semester_id, course_id):
     formset = InlineContributionFormset(request.POST or None, instance=course, queryset=course.contributions.exclude(contributor=None))
 
     if form.is_valid() and formset.is_valid():
+        if course.state in ['evaluated', 'reviewed'] and course.is_in_evaluation_period:
+            course.reopen_evaluation()
         form.save(user=request.user)
         formset.save()
 


Test patch:
diff --git a/evap/staff/fixtures/minimal_test_data.json b/evap/staff/fixtures/minimal_test_data.json
--- a/evap/staff/fixtures/minimal_test_data.json
+++ b/evap/staff/fixtures/minimal_test_data.json
@@ -1151,7 +1151,7 @@
       5, 
       8
     ], 
-    "vote_end_date": "2014-09-30", 
+    "vote_end_date": "2099-12-31", 
     "name_en": "a course", 
     "kind": "a type", 
     "vote_start_date": "2014-09-10"