diff --git a/generic/forms.py b/generic/forms.py index 31a4621a..c4e7e599 100755 --- a/generic/forms.py +++ b/generic/forms.py @@ -12,7 +12,7 @@ from django.forms import ( DateField, SplitDateTimeField, SplitDateTimeWidget, - + BooleanField, ) from django.forms import inlineformset_factory from atlas.models import CaseCollection @@ -812,6 +812,12 @@ 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) + create_supervisor = BooleanField( + required=False, + label="Create linked supervisor account", + help_text="If checked, a supervisor profile with this user's name and email will be automatically created.", + initial=False, + ) class TraineeForm(Form): diff --git a/generic/templates/generic/trainee_creation_form.html b/generic/templates/generic/trainee_creation_form.html index ab2ab962..23a4be99 100755 --- a/generic/templates/generic/trainee_creation_form.html +++ b/generic/templates/generic/trainee_creation_form.html @@ -1,30 +1,42 @@ {% extends "generic/base.html" %} - - {% load crispy_forms_tags %} -{% block css %} -{% endblock %} + {% block js %} - -{{form.media}} - - - - + {{ 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 }} -
- -
+{% block content %} +
+
+
+
+
+

Create Trainee

+
+
+

Use this form to create a user. Only existing supervisors can be added (if they don't exist, create them first and refresh this page or add them later).

+ + {% if errors %} + + {% endif %} + +
+ {% csrf_token %} + {{ form|crispy }} +
+ + Cancel + + +
+
+
+
+
+
+
{% endblock %} \ No newline at end of file diff --git a/generic/templates/generic/user_creation_form.html b/generic/templates/generic/user_creation_form.html index 9459c75d..e8961431 100755 --- a/generic/templates/generic/user_creation_form.html +++ b/generic/templates/generic/user_creation_form.html @@ -1,30 +1,42 @@ {% extends "generic/base.html" %} - {% load crispy_forms_tags %} -{% block css %} -{% endblock %} {% block js %} - -{{form.media}} - - - - + {{ form.media }} {% endblock %} -{% block content %} -

Create User

-Use this form to create a user. Create a trainee here. -{% if errors %} - -{% endif %} -
- {% csrf_token %} - - {{ form|crispy }} -
- -
+{% block content %} +
+
+
+
+
+

Create User

+
+
+

Use this form to create a new user. To create a trainee instead, click here.

+ + {% if errors %} + + {% endif %} + +
+ {% csrf_token %} + {{ form|crispy }} +
+ + Cancel + + +
+
+
+
+
+
+
{% endblock %} \ No newline at end of file diff --git a/generic/views.py b/generic/views.py index 14590d8c..06194589 100644 --- a/generic/views.py +++ b/generic/views.py @@ -5948,9 +5948,22 @@ def create_user(request, context=None, trainee: bool = False): if trainee and form.cleaned_data.get("supervisor"): supervisor = form.cleaned_data["supervisor"] user_profile.supervisor = supervisor - user_profile.save() + if not trainee and form.cleaned_data.get("create_supervisor"): + from generic.models import Supervisor + supervisor, created = Supervisor.objects.get_or_create( + email=new_user.email, + defaults={ + "name": f"{new_user.first_name} {new_user.last_name}".strip(), + "user": new_user, + } + ) + if not created and not supervisor.user: + supervisor.user = new_user + supervisor.name = f"{new_user.first_name} {new_user.last_name}".strip() + supervisor.save(update_fields=["user", "name"]) + except Exception as error: errors = f"Unable to create account profile {error}" return render( diff --git a/rad/tests/test_user_access.py b/rad/tests/test_user_access.py index 09a5c7e7..34f8562f 100644 --- a/rad/tests/test_user_access.py +++ b/rad/tests/test_user_access.py @@ -280,5 +280,57 @@ def test_hide_exams_and_collections(client, create_users): assert b"Test Physics Exam" in response_unhidden.content +@pytest.mark.django_db +def test_create_user_with_linked_supervisor(client, create_cid_manager, django_user_model): + from generic.models import Supervisor + + client.force_login(create_cid_manager) + + # 1. Create a user WITH create_supervisor checked + response = client.post( + reverse("create_user"), + { + "username": "newsupervisor@example.com", + "first_name": "New", + "last_name": "Supervisor", + "grade": "", + "create_supervisor": True, + }, + ) + + assert response.status_code == 302 + assert response.url == reverse("accounts_list") + + # Verify user created + new_user = django_user_model.objects.get(username="newsupervisor@example.com") + assert new_user.first_name == "New" + assert new_user.last_name == "Supervisor" + + # Verify linked supervisor created + supervisor = Supervisor.objects.get(email="newsupervisor@example.com") + assert supervisor.name == "New Supervisor" + assert supervisor.user == new_user + + # 2. Create a user WITHOUT create_supervisor checked + response_no_sv = client.post( + reverse("create_user"), + { + "username": "regularuser@example.com", + "first_name": "Regular", + "last_name": "User", + "grade": "", + "create_supervisor": False, + }, + ) + + assert response_no_sv.status_code == 302 + + # Verify user created + regular_user = django_user_model.objects.get(username="regularuser@example.com") + # Verify no supervisor was created + assert not Supervisor.objects.filter(email="regularuser@example.com").exists() + + +