Add functionality to create linked supervisor account when creating a user
This commit is contained in:
+7
-1
@@ -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):
|
||||
|
||||
@@ -1,30 +1,42 @@
|
||||
{% extends "generic/base.html" %}
|
||||
<!-- {% load static from static %} -->
|
||||
|
||||
{% load crispy_forms_tags %}
|
||||
{% block css %}
|
||||
{% endblock %}
|
||||
|
||||
{% block js %}
|
||||
<!--<script type="text/javascript" src="/admin/jsi18n/"></script>-->
|
||||
{{form.media}}
|
||||
|
||||
<script type="text/javascript">
|
||||
</script>
|
||||
|
||||
<!-- {{ form.media }} -->
|
||||
{{ form.media }}
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<h2>Create Trainee</h2>
|
||||
Use this form to create a user. Only existing supervisors can be added (<a href="{% url 'generic:supervisor_create' %}">create them first</a> and refresh this page or add them later if they do not exist).
|
||||
{% if errors %}
|
||||
<div class="alert alert-info" role="alert">{{errors}}</a></div>
|
||||
{% endif %}
|
||||
<form action="" method="post" enctype="multipart/form-data" id="condition-form">
|
||||
{% csrf_token %}
|
||||
|
||||
<table>
|
||||
{{ form|crispy }}
|
||||
</table>
|
||||
<input type="submit" class="submit-button" value="Submit" name="submit">
|
||||
</form>
|
||||
{% block content %}
|
||||
<div class="container py-4">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card shadow-sm border border-secondary border-opacity-20">
|
||||
<div class="card-header bg-primary text-white py-3">
|
||||
<h4 class="mb-0"><i class="bi bi-person-plus me-2"></i>Create Trainee</h4>
|
||||
</div>
|
||||
<div class="card-body p-4">
|
||||
<p class="text-muted mb-4">Use this form to create a user. Only existing supervisors can be added (if they don't exist, <a href="{% url 'generic:supervisor_create' %}" class="fw-bold">create them first</a> and refresh this page or add them later).</p>
|
||||
|
||||
{% if errors %}
|
||||
<div class="alert alert-danger" role="alert">
|
||||
<i class="bi bi-exclamation-triangle-fill me-2"></i>{{ errors }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<form action="" method="post" enctype="multipart/form-data" id="condition-form">
|
||||
{% csrf_token %}
|
||||
{{ form|crispy }}
|
||||
<div class="mt-4 d-flex justify-content-between">
|
||||
<a href="{% url 'accounts_list' %}" class="btn btn-outline-secondary">
|
||||
<i class="bi bi-x-lg me-1"></i>Cancel
|
||||
</a>
|
||||
<button type="submit" class="btn btn-primary px-4">
|
||||
<i class="bi bi-check-lg me-1"></i>Create Trainee
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -1,30 +1,42 @@
|
||||
{% extends "generic/base.html" %}
|
||||
<!-- {% load static from static %} -->
|
||||
{% load crispy_forms_tags %}
|
||||
|
||||
{% block css %}
|
||||
{% endblock %}
|
||||
{% block js %}
|
||||
<!--<script type="text/javascript" src="/admin/jsi18n/"></script>-->
|
||||
{{form.media}}
|
||||
|
||||
<script type="text/javascript">
|
||||
</script>
|
||||
|
||||
<!-- {{ form.media }} -->
|
||||
{{ form.media }}
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<h2>Create User</h2>
|
||||
Use this form to create a user. Create a trainee <a href="{% url 'create_trainee' %}">here</a>.
|
||||
{% if errors %}
|
||||
<div class="alert alert-info" role="alert">{{errors}}</a></div>
|
||||
{% endif %}
|
||||
<form action="" method="post" enctype="multipart/form-data" id="condition-form">
|
||||
{% csrf_token %}
|
||||
|
||||
<table>
|
||||
{{ form|crispy }}
|
||||
</table>
|
||||
<input type="submit" class="submit-button" value="Submit" name="submit">
|
||||
</form>
|
||||
{% block content %}
|
||||
<div class="container py-4">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card shadow-sm border border-secondary border-opacity-20">
|
||||
<div class="card-header bg-primary text-white py-3">
|
||||
<h4 class="mb-0"><i class="bi bi-person-plus me-2"></i>Create User</h4>
|
||||
</div>
|
||||
<div class="card-body p-4">
|
||||
<p class="text-muted mb-4">Use this form to create a new user. To create a trainee instead, click <a href="{% url 'create_trainee' %}" class="fw-bold">here</a>.</p>
|
||||
|
||||
{% if errors %}
|
||||
<div class="alert alert-danger" role="alert">
|
||||
<i class="bi bi-exclamation-triangle-fill me-2"></i>{{ errors }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<form action="" method="post" enctype="multipart/form-data" id="condition-form">
|
||||
{% csrf_token %}
|
||||
{{ form|crispy }}
|
||||
<div class="mt-4 d-flex justify-content-between">
|
||||
<a href="{% url 'accounts_list' %}" class="btn btn-outline-secondary">
|
||||
<i class="bi bi-x-lg me-1"></i>Cancel
|
||||
</a>
|
||||
<button type="submit" class="btn btn-primary px-4">
|
||||
<i class="bi bi-check-lg me-1"></i>Create User
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
+14
-1
@@ -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(
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user