Repository: UTNkar/moore

Issue:
Use person number for appoint->overturn field
<!-- Do you want to ask a question? Are you looking for support? The system administrator can help you: admin@utn.se -->

### Prerequisites

* [X] Put an X between the brackets on this line if you have done all of the
following:
    * Reproduced the problem with clear cache.
    * (If running the application locally:) Made sure your running the newest version on the development branch
    * Checked that your issue isn't already filed: https://github.com/UTNkar/moore/issues

### Description

Currently the `overturn` field within the `appoint` view of `Position` has a overturn field that works with usernames. The username(s) entered will be appointed to the position, no matter if they applied or not.

_Problem_: Within the old system a similar feature was available, but it was by person number. According to the management team this is preferable.

### Steps to Reproduce

1. Create new `Position` with past deadline
2. Click `appoint` in the overview

<!-- Please select the appropriate "topic category"/blue and "issue type"/yellow label -->


Discussion:

Resolving patch:
diff --git a/src/involvement/forms.py b/src/involvement/forms.py
--- a/src/involvement/forms.py
+++ b/src/involvement/forms.py
@@ -3,6 +3,7 @@
 from django.utils.translation import ugettext_lazy as _
 
 from involvement.models import Application, Reference
+from members.forms import PersonNumberField
 from utils.forms import AdvancedModelMultipleChoiceField
 
 
@@ -75,9 +76,9 @@ class AppointmentForm(forms.Form):
     overturn = forms.CharField(
         required=False,
         label=_('Overturn'),
-        help_text=_('Enter a comma separated list of users you want to '
-                    'appoint to the position, even though did not apply for '
-                    'the position.')
+        help_text=_('Enter a comma separated list of person numbers you want '
+                    'to appoint to the position, even though did not apply for'
+                    ' the position.')
     )
 
     def __init__(self, position, *args, **kwargs):
@@ -96,26 +97,35 @@ def clean_overturn(self):
         if string == '':
             return []
         else:
-            users = string.split(',')
-            for u in users:
+            pnrs = string.split(',')
+            users = []
+            for pnr in pnrs:
+                date, number = PersonNumberField().to_python(pnr)
                 if not get_user_model().objects.filter(
-                    username=u
+                    birthday=date,
+                    person_number_ext=number,
                 ).exists():
                     raise forms.ValidationError(
-                        _('No user with the username %(user)s exists.'),
-                        params={'user': u},
+                        _('No user with the person number %(pnr)s exists.'),
+                        params={'pnr': pnr},
                     )
                 elif self.position.applications.filter(
-                    applicant__username=u
+                    applicant__birthday=date,
+                    applicant__person_number_ext=number,
                 ).exclude(
                     status='draft'
                 ).exists():
                     raise forms.ValidationError(
-                        _('User %(user)s already applied for this position '
-                          'and can not be appointed through the overturn '
-                          'field.'),
-                        params={'user': u},
+                        _('User with person number %(pnr)s already applied for'
+                          ' this position and can not be appointed through the'
+                          ' overturn field.'),
+                        params={'pnr': pnr},
                     )
+                else:
+                    users.append(get_user_model().objects.get(
+                        birthday=date,
+                        person_number_ext=number,
+                    ))
             return users
 
     def clean(self):
@@ -143,9 +153,6 @@ def save(self):
             application.save()
 
         for user in self.cleaned_data['overturn']:
-            user = get_user_model().objects.get(
-                    username=user
-            )
             appl, created = Application.objects.get_or_create(
                 position=self.position,
                 applicant=user,


Test patch: