diff --git a/generic/forms.py b/generic/forms.py index 96f7c303..99f19b60 100755 --- a/generic/forms.py +++ b/generic/forms.py @@ -68,6 +68,8 @@ from django.forms.utils import from_current_timezone, to_current_timezone from crispy_forms.helper import FormHelper from crispy_forms.layout import Submit +from dal import autocomplete + class SplitDateTimeFieldDefaultTime(SplitDateTimeField): def compress(self, data_list): @@ -672,13 +674,23 @@ class UserUserForm(Form): first_name = CharField(max_length=255, required=True) last_name = CharField(max_length=255, required=True) grade = ModelChoiceField(UserGrades.objects.all(), required=False) + +class TraineeForm(Form): + username = EmailField( + required=True, + help_text="Username / email should be the same. Ideally this should be an nhs email.", + ) + first_name = CharField(max_length=255, required=True) + last_name = CharField(max_length=255, required=True) + grade = ModelChoiceField(UserGrades.objects.all(), required=False) supervisor = ModelChoiceField( - Supervisor.objects.all(), required=False + Supervisor.objects.all(), required=False, widget=autocomplete.ModelSelect2(url='generic:supervisor-autocomplete') ) # Needs to be a user/object ref - # - # class Meta: - # - # fields = ("username", "first_name", "last_name") + + #class Meta: + # widgets = { + # "supervisor" : autocomplete.ModelSelect2(url='generic:supervisor-autocomplete') + # } class SupervisorForm(ModelForm): diff --git a/generic/templates/generic/trainee_creation_form.html b/generic/templates/generic/trainee_creation_form.html new file mode 100755 index 00000000..ab2ab962 --- /dev/null +++ b/generic/templates/generic/trainee_creation_form.html @@ -0,0 +1,30 @@ +{% extends "generic/base.html" %} + + +{% load crispy_forms_tags %} +{% block css %} +{% endblock %} +{% block js %} + +{{form.media}} + + + + +{% endblock %} +{% block content %} +

Create Trainee

+Use this form to create a user. Only existing supervisors can be added (create them first and refresh this page or add them later if they do not exist). +{% if errors %} + +{% endif %} +
+ {% csrf_token %} + + + {{ form|crispy }} +
+ +
+{% endblock %} \ No newline at end of file diff --git a/generic/templates/generic/trainees.html b/generic/templates/generic/trainees.html index 1d1e5389..7aafa2fe 100644 --- a/generic/templates/generic/trainees.html +++ b/generic/templates/generic/trainees.html @@ -9,7 +9,7 @@ {% for i in "123456"|make_list %} ST{{i}}{% if not forloop.last %}, {% endif %} {% endfor %} - Add trainee + (Add trainee)

{% if grade %} diff --git a/generic/templates/generic/user_creation_form.html b/generic/templates/generic/user_creation_form.html index d0c02f22..9459c75d 100755 --- a/generic/templates/generic/user_creation_form.html +++ b/generic/templates/generic/user_creation_form.html @@ -1,5 +1,6 @@ {% extends "generic/base.html" %} +{% load crispy_forms_tags %} {% block css %} {% endblock %} @@ -13,8 +14,8 @@ {% endblock %} {% block content %} -

Edit User / {{ciduser.cid}}

-Use this form to create a user. Only existing supervisors can be added (create them first and refresh this page or add them later if they do not exist). +

Create User

+Use this form to create a user. Create a trainee here. {% if errors %} {% endif %} @@ -22,7 +23,7 @@ Use this form to create a user. Only existing supervisors can be added ( - {{ form.as_table }} + {{ form|crispy }} diff --git a/generic/urls.py b/generic/urls.py index f68b8397..023265a6 100755 --- a/generic/urls.py +++ b/generic/urls.py @@ -1,6 +1,6 @@ from django.urls import path, include -from generic.models import Examination +from generic.models import Examination, Supervisor from . import views from generic.views import ExamViews as GenericExamViews, GenericViewBase @@ -42,6 +42,13 @@ urlpatterns = [ ), name="examination-autocomplete", ), + path( + "supervisor-autocomplete", + views.SupervisorAutocomplete.as_view( + model=Supervisor + ), + name="supervisor-autocomplete", + ), path( "cids/manage//update", views.CidUserUpdate.as_view(), name="update_cid" ), diff --git a/generic/views.py b/generic/views.py index f47e29e1..2b522c0f 100644 --- a/generic/views.py +++ b/generic/views.py @@ -53,7 +53,7 @@ from generic.mixins import CheckCanEditMixin, SuperuserRequiredMixin import zipfile from django.core.files.base import ContentFile - +from django.db.models import Q from .forms import ( CidGroupExamForm, @@ -65,6 +65,7 @@ from .forms import ( CidUserGroupForm, ExaminationMergeForm, SupervisorForm, + TraineeForm, UserGroupExamForm, CidGroupExamForm, UserUserForm, @@ -2608,6 +2609,23 @@ class ExaminationAutocomplete(autocomplete.Select2QuerySetView): return Examination.objects.none() return qs +class SupervisorAutocomplete(autocomplete.Select2QuerySetView): + def get_queryset(self): + # TODO: we should probably filter this to only + # allow access by trainees / other suprevisors + if not self.request.user.is_authenticated: + return Supervisor.objects.none() + + qs = Supervisor.objects.all() + + if self.q: + # This raises a fielderror which breaks creating a new item if not caught + try: + qs = qs.filter(Q(email__icontains=self.q) | Q(name__icontains=self.q)) + except FieldError: + return Supervisor.objects.none() + + return qs class CidUserExamView(CidManagerRequiredMixin, SingleTableMixin, FilterView): @@ -3364,12 +3382,24 @@ def trainees(request, grade: None|str=None): return render(request, "generic/trainees.html", context) -def create_user(request, context=None): +def create_trainee(request, context=None): + return create_user(request, context, trainee=True) + +@user_is_cid_user_manager +def create_user(request, context=None, trainee: bool=False): + if trainee: + form_template = "generic/trainee_creation_form.html" + else: + form_template = "generic/user_creation_form.html" # if this is a POST request we need to process the form data if request.method == "POST": # create a form instance and populate it with data from the request: - form = UserUserForm(request.POST) + if trainee: + form = TraineeForm(request.POST) + else: + form = UserUserForm(request.POST) # check whether it's valid: + if form.is_valid(): try: user_dict = { @@ -3385,19 +3415,19 @@ def create_user(request, context=None): errors = f"Unable to create account: {error}" return render( request, - "generic/user_creation_form.html", + form_template, {"form": form, "errors": errors}, ) try: user_profile = UserProfile.objects.get(user=new_user) - user_profile.peninsula_trainee = True + user_profile.peninsula_trainee = trainee if request.POST["grade"]: grade = UserGrades.objects.get(pk=request.POST["grade"]) user_profile.grade = grade - if request.POST["supervisor"]: + if "supervisor" in request.POST and request.POST["supervisor"]: supervisor = Supervisor.objects.get(pk=request.POST["supervisor"]) user_profile.supervisor = supervisor @@ -3407,7 +3437,7 @@ def create_user(request, context=None): errors = f"Unable to create account profile {error}" return render( request, - "generic/user_creation_form.html", + form_template, {"form": form, "errors": errors}, ) @@ -3416,9 +3446,12 @@ def create_user(request, context=None): # if a GET (or any other method) we'll create a blank form else: - form = UserUserForm() + if trainee: + form = TraineeForm() + else: + form = UserUserForm() - return render(request, "generic/user_creation_form.html", {"form": form}) + return render(request, form_template, {"form": form}) class SupervisorDetail(CidManagerRequiredMixin, DetailView): diff --git a/rad/urls.py b/rad/urls.py index f790ece9..90a1418c 100644 --- a/rad/urls.py +++ b/rad/urls.py @@ -75,6 +75,9 @@ urlpatterns = [ path( "accounts/create/", generic_views.create_user, name="create_user" ), + path( + "accounts/trainees/create/", generic_views.create_trainee, name="create_trainee" + ), path( "accounts/trainees/", generic_views.trainees, name="trainees" ),