Repository: carpentries/amy

Issue:
Should be able to add a task from the 'Edit Person' page
We can add Awards from the 'Edit Person' page - should also be able to add tasks.



Discussion:

Resolving patch:
diff --git a/workshops/forms.py b/workshops/forms.py
--- a/workshops/forms.py
+++ b/workshops/forms.py
@@ -343,3 +343,19 @@ class Meta:
         model = Award
         fields = '__all__'
         widgets = {'person': HiddenInput}
+
+
+class PersonTaskForm(forms.ModelForm):
+
+    event = selectable.AutoCompleteSelectField(
+        lookup_class=lookups.EventLookup,
+        label='Event',
+        required=True,
+        help_text=AUTOCOMPLETE_HELP_TEXT,
+        widget=selectable.AutoComboboxSelectWidget,
+    )
+
+    class Meta:
+        model = Task
+        fields = '__all__'
+        widgets = {'person': HiddenInput}
diff --git a/workshops/views.py b/workshops/views.py
--- a/workshops/views.py
+++ b/workshops/views.py
@@ -40,6 +40,7 @@
     EventForm, TaskForm, TaskFullForm, bootstrap_helper,
     bootstrap_helper_with_add, BadgeAwardForm, PersonAwardForm,
     PersonPermissionsForm, bootstrap_helper_filter, PersonMergeForm,
+    PersonTaskForm,
 )
 from workshops.util import (
     earth_distance, upload_person_task_csv,  verify_upload_person_task,
@@ -452,6 +453,7 @@ def person_edit(request, person_id):
     try:
         person = Person.objects.get(pk=person_id)
         awards = person.award_set.order_by('badge__name')
+        tasks = person.task_set.order_by('-event__slug')
     except ObjectDoesNotExist:
         raise Http404("No person found matching the query.")
 
@@ -460,6 +462,7 @@ def person_edit(request, person_id):
         'awarded': datetime.date.today(),
         'person': person,
     })
+    task_form = PersonTaskForm(prefix='task', initial={'person': person})
 
     if request.method == 'POST':
         # check which form was submitted
@@ -475,13 +478,39 @@ def person_edit(request, person_id):
                         person=str(person),
                         badge=award.badge.title,
                     ),
+                    extra_tags='awards',
                 )
 
                 # to reset the form values
                 return redirect(request.path)
 
             else:
-                messages.error(request, 'Fix errors below.')
+                messages.error(request, 'Fix errors in the award form.',
+                               extra_tags='awards')
+
+        elif 'task-role' in request.POST:
+            task_form = PersonTaskForm(request.POST, prefix='task')
+
+            if task_form.is_valid():
+                task = task_form.save()
+
+                messages.success(
+                    request,
+                    '{person} was added a role {role} during {event} event.'
+                    .format(
+                        person=str(person),
+                        role=task.role.name,
+                        event=task.event.slug,
+                    ),
+                    extra_tags='tasks',
+                )
+
+                # to reset the form values
+                return redirect(request.path)
+
+            else:
+                messages.error(request, 'Fix errors in the task form.',
+                               extra_tags='tasks')
 
         else:
             person_form = PersonForm(request.POST, prefix='person',
@@ -520,6 +549,8 @@ def person_edit(request, person_id):
                'model': Person,
                'awards': awards,
                'award_form': award_form,
+               'tasks': tasks,
+               'task_form': task_form,
                'form_helper': bootstrap_helper,
                'form_helper_with_add': bootstrap_helper_with_add,
                }


Test patch:
diff --git a/workshops/test/test_person.py b/workshops/test/test_person.py
--- a/workshops/test/test_person.py
+++ b/workshops/test/test_person.py
@@ -184,6 +184,30 @@ def test_person_award_badge(self):
         self.spiderman.refresh_from_db()
         assert self.instructor == self.spiderman.award_set.all()[0].badge
 
+    def test_person_add_task(self):
+        self._setUpEvents()  # set up some events for us
+
+        # make sure person has no tasks
+        assert not self.spiderman.task_set.all()
+
+        # add new task
+        url, values = self._get_initial_form_index(2, 'person_edit',
+                                                   self.spiderman.id)
+        assert 'task-role' in values
+
+        role = Role.objects.create(name='test_role')
+        values['task-event_1'] = Event.objects.all()[0].pk
+        values['task-role'] = role.pk
+        rv = self.client.post(url, data=values)
+        assert rv.status_code == 302, \
+            'After adding a task we should be redirected to the same page, ' \
+            'got {} instead'.format(rv.status_code)
+        # we actually can't test if it redirects to the same url…
+
+        # make sure the task was recorded in the database
+        self.spiderman.refresh_from_db()
+        assert role == self.spiderman.task_set.all()[0].role
+
     def test_edit_person_permissions(self):
         "Make sure we can set up user permissions correctly."