We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Application drafts in limbo
<!-- 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

The problem has not been reproduced but it's the kind of problem that probably will occur any way.

When a user starts an application draft and forgets to submit it the person can not be appointed to the position with the overturn function. If the application for a position has been saved as draft when the application period ends the application becomes stuck in limbo. The group administrator can before the application period has ended see that there is a draft for the person. When the application period ends the draft is not visible among the submitted applications (very resonable). The problem occurs when the administrator wants to appoint that person anyway with the overturn function then an error message occurs saying. "You can not appoint this person since an application has been submitted". This should not be the case, a draft application should not be seen as a submitted application by the overturn function. The user can not see or delete the draft application after the application period has ended.

Quick fix, an application system administrator can access the applications and set the status to submitted. 

### Steps to Reproduce

1. Apply to an position and save the application as draft
2. Wait for the application time to end
3. Go to appoint for the given position
4. Try overturn with the user who saved the application as draft
5. Error message occurs 

<!-- Please select the appropriate "topic category"/blue and "issue type"/yellow label -->

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `website/involvement/forms.py`
Content:
```
1 from django import forms
2 from django.contrib.auth import get_user_model
3 from django.utils.translation import ugettext_lazy as _
4 
5 from involvement.models import Application, Reference
6 from utils.forms import AdvancedModelMultipleChoiceField
7 
8 
9 class ApplicationForm(forms.ModelForm):
10     class Meta:
11         model = Application
12         exclude = ['position', 'applicant']
13         widgets = {
14             'cover_letter': forms.Textarea(attrs={'style': 'height: 200px',
15                                                   'class': 'form-control'}),
16             'qualifications': forms.Textarea(attrs={'style': 'height: 200px',
17                                                     'class': 'form-control'}),
18         }
19 
20     def clean_status(self):
21         status = self.cleaned_data['status']
22         if status not in ['draft', 'submitted'] \
23                 or (self.initial['status'] == 'submitted'
24                     and status == 'draft'):
25             raise forms.ValidationError(_('The submitted status was invalid.'))
26         return status
27 
28 
29 ReferenceFormSet = forms.inlineformset_factory(
30     Application,
31     Reference,
32     fields=('name', 'position', 'email', 'phone_number', 'comment'),
33     widgets={
34         'name': forms.TextInput(attrs={'class': 'form-control'}),
35         'position': forms.TextInput(attrs={'class': 'form-control'}),
36         'email': forms.TextInput(attrs={'class': 'form-control'}),
37         'phone_number': forms.TextInput(attrs={'class': 'form-control'}),
38         'comment': forms.TextInput(attrs={'class': 'form-control'}),
39     },
40     extra=0,
41 )
42 
43 
44 class ApprovalForm(forms.ModelForm):
45     status = forms.ChoiceField(
46         choices=(
47             ('submitted', '---------'),
48             ('approved', _('Approved')),
49             ('disapproved', _('Disapproved')),
50         ),
51     )
52 
53     class Meta:
54         model = Application
55         fields = []
56 
57     def clean_status(self):
58         status = self.cleaned_data['status']
59         if status not in ['submitted', 'approved', 'disapproved']:
60             raise forms.ValidationError(_('The submitted status was invalid.'))
61         return status
62 
63     def save(self, commit=True):
64         self.instance.status = self.cleaned_data['status']
65 
66         super(ApprovalForm, self).save(commit)
67 
68 
69 class AppointmentForm(forms.Form):
70     appoint = AdvancedModelMultipleChoiceField(
71         Application.objects.none(),
72         widget=forms.CheckboxSelectMultiple(),
73         required=False,
74     )
75     overturn = forms.CharField(
76         required=False,
77         label=_('Overturn'),
78         help_text=_('Enter a comma separated list of users you want to '
79                     'appoint to the position, even though did not apply for '
80                     'the position.')
81     )
82 
83     def __init__(self, position, *args, **kwargs):
84         super(AppointmentForm, self).__init__(*args, **kwargs)
85         self.position = position
86         self.fields['appoint'].queryset = position.applications.filter(
87             status__in=['submitted', 'approved', 'appointed', 'turned_down']
88         )
89         self.initial['appoint'] = position.applications.filter(
90             status='appointed'
91         )
92 
93     def clean_overturn(self):
94         string = self.cleaned_data['overturn']
95         string = string.replace(' ', '')
96         if string == '':
97             return []
98         else:
99             users = string.split(',')
100             for u in users:
101                 if not get_user_model().objects.filter(
102                     username=u
103                 ).exists():
104                     raise forms.ValidationError(
105                         _('No user with the username %(user)s exists.'),
106                         params={'user': u},
107                     )
108                 elif self.position.applications.filter(
109                     applicant__username=u
110                 ).exists():
111                     raise forms.ValidationError(
112                         _('User %(user)s already applied for this position '
113                           'and can not be appointed through the overturn '
114                           'field.'),
115                         params={'user': u},
116                     )
117             return users
118 
119     def clean(self):
120         super(AppointmentForm, self).clean()
121         appoint = self.cleaned_data.get('appoint', [])
122         overturn = self.cleaned_data.get('overturn', [])
123         nr_appointment = len(appoint) + len(overturn)
124         if nr_appointment > self.position.appointments:
125             raise forms.ValidationError(
126                 _('You cannot appoint %(current)s applicants. The maximum '
127                   'for this position is %(max)s.'),
128                 params={
129                     'current': nr_appointment,
130                     'max': self.position.appointments,
131                 },
132             )
133         return self.cleaned_data
134 
135     def save(self):
136         for application in self.fields['appoint'].queryset:
137             if application in self.cleaned_data['appoint']:
138                 application.status = 'appointed'
139             else:
140                 application.status = 'turned_down'
141             application.save()
142 
143         for user in self.cleaned_data['overturn']:
144             user = get_user_model().objects.get(
145                     username=user
146             )
147             Application.objects.create(
148                 position=self.position,
149                 applicant=user,
150                 status='appointed',
151             )
152
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/website/involvement/forms.py b/website/involvement/forms.py
--- a/website/involvement/forms.py
+++ b/website/involvement/forms.py
@@ -107,6 +107,8 @@
                     )
                 elif self.position.applications.filter(
                     applicant__username=u
+                ).exclude(
+                    status='draft'
                 ).exists():
                     raise forms.ValidationError(
                         _('User %(user)s already applied for this position '
@@ -144,8 +146,11 @@
             user = get_user_model().objects.get(
                     username=user
             )
-            Application.objects.create(
+            appl, created = Application.objects.get_or_create(
                 position=self.position,
                 applicant=user,
-                status='appointed',
+                defaults={'status': 'appointed'}
             )
+            if not created:
+                appl.status = 'appointed'
+                appl.save()

{"golden_diff": "diff --git a/website/involvement/forms.py b/website/involvement/forms.py\n--- a/website/involvement/forms.py\n+++ b/website/involvement/forms.py\n@@ -107,6 +107,8 @@\n                     )\n                 elif self.position.applications.filter(\n                     applicant__username=u\n+                ).exclude(\n+                    status='draft'\n                 ).exists():\n                     raise forms.ValidationError(\n                         _('User %(user)s already applied for this position '\n@@ -144,8 +146,11 @@\n             user = get_user_model().objects.get(\n                     username=user\n             )\n-            Application.objects.create(\n+            appl, created = Application.objects.get_or_create(\n                 position=self.position,\n                 applicant=user,\n-                status='appointed',\n+                defaults={'status': 'appointed'}\n             )\n+            if not created:\n+                appl.status = 'appointed'\n+                appl.save()\n", "issue": "Application drafts in limbo\n<!-- Do you want to ask a question? Are you looking for support? The system administrator can help you: admin@utn.se -->\r\n\r\n### Prerequisites\r\n\r\n* [x] Put an X between the brackets on this line if you have done all of the\r\nfollowing:\r\n    * Reproduced the problem with clear cache.\r\n    * (If running the application locally:) Made sure your running the newest version on the development branch\r\n    * Checked that your issue isn't already filed: https://github.com/UTNkar/moore/issues\r\n\r\n### Description\r\n\r\nThe problem has not been reproduced but it's the kind of problem that probably will occur any way.\r\n\r\nWhen a user starts an application draft and forgets to submit it the person can not be appointed to the position with the overturn function. If the application for a position has been saved as draft when the application period ends the application becomes stuck in limbo. The group administrator can before the application period has ended see that there is a draft for the person. When the application period ends the draft is not visible among the submitted applications (very resonable). The problem occurs when the administrator wants to appoint that person anyway with the overturn function then an error message occurs saying. \"You can not appoint this person since an application has been submitted\". This should not be the case, a draft application should not be seen as a submitted application by the overturn function. The user can not see or delete the draft application after the application period has ended.\r\n\r\nQuick fix, an application system administrator can access the applications and set the status to submitted. \r\n\r\n### Steps to Reproduce\r\n\r\n1. Apply to an position and save the application as draft\r\n2. Wait for the application time to end\r\n3. Go to appoint for the given position\r\n4. Try overturn with the user who saved the application as draft\r\n5. Error message occurs \r\n\r\n<!-- Please select the appropriate \"topic category\"/blue and \"issue type\"/yellow label -->\n", "before_files": [{"content": "from django import forms\nfrom django.contrib.auth import get_user_model\nfrom django.utils.translation import ugettext_lazy as _\n\nfrom involvement.models import Application, Reference\nfrom utils.forms import AdvancedModelMultipleChoiceField\n\n\nclass ApplicationForm(forms.ModelForm):\n    class Meta:\n        model = Application\n        exclude = ['position', 'applicant']\n        widgets = {\n            'cover_letter': forms.Textarea(attrs={'style': 'height: 200px',\n                                                  'class': 'form-control'}),\n            'qualifications': forms.Textarea(attrs={'style': 'height: 200px',\n                                                    'class': 'form-control'}),\n        }\n\n    def clean_status(self):\n        status = self.cleaned_data['status']\n        if status not in ['draft', 'submitted'] \\\n                or (self.initial['status'] == 'submitted'\n                    and status == 'draft'):\n            raise forms.ValidationError(_('The submitted status was invalid.'))\n        return status\n\n\nReferenceFormSet = forms.inlineformset_factory(\n    Application,\n    Reference,\n    fields=('name', 'position', 'email', 'phone_number', 'comment'),\n    widgets={\n        'name': forms.TextInput(attrs={'class': 'form-control'}),\n        'position': forms.TextInput(attrs={'class': 'form-control'}),\n        'email': forms.TextInput(attrs={'class': 'form-control'}),\n        'phone_number': forms.TextInput(attrs={'class': 'form-control'}),\n        'comment': forms.TextInput(attrs={'class': 'form-control'}),\n    },\n    extra=0,\n)\n\n\nclass ApprovalForm(forms.ModelForm):\n    status = forms.ChoiceField(\n        choices=(\n            ('submitted', '---------'),\n            ('approved', _('Approved')),\n            ('disapproved', _('Disapproved')),\n        ),\n    )\n\n    class Meta:\n        model = Application\n        fields = []\n\n    def clean_status(self):\n        status = self.cleaned_data['status']\n        if status not in ['submitted', 'approved', 'disapproved']:\n            raise forms.ValidationError(_('The submitted status was invalid.'))\n        return status\n\n    def save(self, commit=True):\n        self.instance.status = self.cleaned_data['status']\n\n        super(ApprovalForm, self).save(commit)\n\n\nclass AppointmentForm(forms.Form):\n    appoint = AdvancedModelMultipleChoiceField(\n        Application.objects.none(),\n        widget=forms.CheckboxSelectMultiple(),\n        required=False,\n    )\n    overturn = forms.CharField(\n        required=False,\n        label=_('Overturn'),\n        help_text=_('Enter a comma separated list of users you want to '\n                    'appoint to the position, even though did not apply for '\n                    'the position.')\n    )\n\n    def __init__(self, position, *args, **kwargs):\n        super(AppointmentForm, self).__init__(*args, **kwargs)\n        self.position = position\n        self.fields['appoint'].queryset = position.applications.filter(\n            status__in=['submitted', 'approved', 'appointed', 'turned_down']\n        )\n        self.initial['appoint'] = position.applications.filter(\n            status='appointed'\n        )\n\n    def clean_overturn(self):\n        string = self.cleaned_data['overturn']\n        string = string.replace(' ', '')\n        if string == '':\n            return []\n        else:\n            users = string.split(',')\n            for u in users:\n                if not get_user_model().objects.filter(\n                    username=u\n                ).exists():\n                    raise forms.ValidationError(\n                        _('No user with the username %(user)s exists.'),\n                        params={'user': u},\n                    )\n                elif self.position.applications.filter(\n                    applicant__username=u\n                ).exists():\n                    raise forms.ValidationError(\n                        _('User %(user)s already applied for this position '\n                          'and can not be appointed through the overturn '\n                          'field.'),\n                        params={'user': u},\n                    )\n            return users\n\n    def clean(self):\n        super(AppointmentForm, self).clean()\n        appoint = self.cleaned_data.get('appoint', [])\n        overturn = self.cleaned_data.get('overturn', [])\n        nr_appointment = len(appoint) + len(overturn)\n        if nr_appointment > self.position.appointments:\n            raise forms.ValidationError(\n                _('You cannot appoint %(current)s applicants. The maximum '\n                  'for this position is %(max)s.'),\n                params={\n                    'current': nr_appointment,\n                    'max': self.position.appointments,\n                },\n            )\n        return self.cleaned_data\n\n    def save(self):\n        for application in self.fields['appoint'].queryset:\n            if application in self.cleaned_data['appoint']:\n                application.status = 'appointed'\n            else:\n                application.status = 'turned_down'\n            application.save()\n\n        for user in self.cleaned_data['overturn']:\n            user = get_user_model().objects.get(\n                    username=user\n            )\n            Application.objects.create(\n                position=self.position,\n                applicant=user,\n                status='appointed',\n            )\n", "path": "website/involvement/forms.py"}], "after_files": [{"content": "from django import forms\nfrom django.contrib.auth import get_user_model\nfrom django.utils.translation import ugettext_lazy as _\n\nfrom involvement.models import Application, Reference\nfrom utils.forms import AdvancedModelMultipleChoiceField\n\n\nclass ApplicationForm(forms.ModelForm):\n    class Meta:\n        model = Application\n        exclude = ['position', 'applicant']\n        widgets = {\n            'cover_letter': forms.Textarea(attrs={'style': 'height: 200px',\n                                                  'class': 'form-control'}),\n            'qualifications': forms.Textarea(attrs={'style': 'height: 200px',\n                                                    'class': 'form-control'}),\n        }\n\n    def clean_status(self):\n        status = self.cleaned_data['status']\n        if status not in ['draft', 'submitted'] \\\n                or (self.initial['status'] == 'submitted'\n                    and status == 'draft'):\n            raise forms.ValidationError(_('The submitted status was invalid.'))\n        return status\n\n\nReferenceFormSet = forms.inlineformset_factory(\n    Application,\n    Reference,\n    fields=('name', 'position', 'email', 'phone_number', 'comment'),\n    widgets={\n        'name': forms.TextInput(attrs={'class': 'form-control'}),\n        'position': forms.TextInput(attrs={'class': 'form-control'}),\n        'email': forms.TextInput(attrs={'class': 'form-control'}),\n        'phone_number': forms.TextInput(attrs={'class': 'form-control'}),\n        'comment': forms.TextInput(attrs={'class': 'form-control'}),\n    },\n    extra=0,\n)\n\n\nclass ApprovalForm(forms.ModelForm):\n    status = forms.ChoiceField(\n        choices=(\n            ('submitted', '---------'),\n            ('approved', _('Approved')),\n            ('disapproved', _('Disapproved')),\n        ),\n    )\n\n    class Meta:\n        model = Application\n        fields = []\n\n    def clean_status(self):\n        status = self.cleaned_data['status']\n        if status not in ['submitted', 'approved', 'disapproved']:\n            raise forms.ValidationError(_('The submitted status was invalid.'))\n        return status\n\n    def save(self, commit=True):\n        self.instance.status = self.cleaned_data['status']\n\n        super(ApprovalForm, self).save(commit)\n\n\nclass AppointmentForm(forms.Form):\n    appoint = AdvancedModelMultipleChoiceField(\n        Application.objects.none(),\n        widget=forms.CheckboxSelectMultiple(),\n        required=False,\n    )\n    overturn = forms.CharField(\n        required=False,\n        label=_('Overturn'),\n        help_text=_('Enter a comma separated list of users you want to '\n                    'appoint to the position, even though did not apply for '\n                    'the position.')\n    )\n\n    def __init__(self, position, *args, **kwargs):\n        super(AppointmentForm, self).__init__(*args, **kwargs)\n        self.position = position\n        self.fields['appoint'].queryset = position.applications.filter(\n            status__in=['submitted', 'approved', 'appointed', 'turned_down']\n        )\n        self.initial['appoint'] = position.applications.filter(\n            status='appointed'\n        )\n\n    def clean_overturn(self):\n        string = self.cleaned_data['overturn']\n        string = string.replace(' ', '')\n        if string == '':\n            return []\n        else:\n            users = string.split(',')\n            for u in users:\n                if not get_user_model().objects.filter(\n                    username=u\n                ).exists():\n                    raise forms.ValidationError(\n                        _('No user with the username %(user)s exists.'),\n                        params={'user': u},\n                    )\n                elif self.position.applications.filter(\n                    applicant__username=u\n                ).exclude(\n                    status='draft'\n                ).exists():\n                    raise forms.ValidationError(\n                        _('User %(user)s already applied for this position '\n                          'and can not be appointed through the overturn '\n                          'field.'),\n                        params={'user': u},\n                    )\n            return users\n\n    def clean(self):\n        super(AppointmentForm, self).clean()\n        appoint = self.cleaned_data.get('appoint', [])\n        overturn = self.cleaned_data.get('overturn', [])\n        nr_appointment = len(appoint) + len(overturn)\n        if nr_appointment > self.position.appointments:\n            raise forms.ValidationError(\n                _('You cannot appoint %(current)s applicants. The maximum '\n                  'for this position is %(max)s.'),\n                params={\n                    'current': nr_appointment,\n                    'max': self.position.appointments,\n                },\n            )\n        return self.cleaned_data\n\n    def save(self):\n        for application in self.fields['appoint'].queryset:\n            if application in self.cleaned_data['appoint']:\n                application.status = 'appointed'\n            else:\n                application.status = 'turned_down'\n            application.save()\n\n        for user in self.cleaned_data['overturn']:\n            user = get_user_model().objects.get(\n                    username=user\n            )\n            appl, created = Application.objects.get_or_create(\n                position=self.position,\n                applicant=user,\n                defaults={'status': 'appointed'}\n            )\n            if not created:\n                appl.status = 'appointed'\n                appl.save()\n", "path": "website/involvement/forms.py"}]}