From 7eeb989b9e46339b597066baafee06ea26024c37 Mon Sep 17 00:00:00 2001
From: Ross
Date: Mon, 3 Nov 2025 09:31:55 +0000
Subject: [PATCH] Enhance supervisor email handling and input format options in
bulk user creation
---
rad/views.py | 68 ++++++++++++++++-----
templates/accounts_bulk_create.html | 91 ++++++++++++++++++++++-------
2 files changed, 123 insertions(+), 36 deletions(-)
diff --git a/rad/views.py b/rad/views.py
index 44ea3eae..3004fe8c 100644
--- a/rad/views.py
+++ b/rad/views.py
@@ -815,8 +815,20 @@ def accounts_bulk_create_check(request):
if not UserGrades.objects.filter(name=user["grade"]):
errors.append("Invalid grade")
- if user["supervisor_email"] == "undefined":
- errors.append("No supervisor email provided")
+ # Treat empty, missing or the string 'undefined' as no supervisor email provided
+ if not user.get("supervisor_email") or user["supervisor_email"] == "undefined":
+ # Supervisor email not provided; try to match by name
+ if not user.get("supervisor_name"):
+ errors.append("No supervisor provided")
+ else:
+ supervisor = Supervisor.objects.filter(name__iexact=user["supervisor_name"])
+ if not supervisor.exists():
+ info.append("Supervisor does not exist (will be created)")
+ else:
+ info.append("Supervisor exists (matched by name)")
+ if supervisor.count() > 1:
+ errors.append("More than one supervisor with that name")
+ # no further name check needed since matched by name
else:
supervisor = Supervisor.objects.filter(email=user["supervisor_email"])
@@ -828,8 +840,14 @@ def accounts_bulk_create_check(request):
if supervisor.count() > 1:
errors.append("More than one supervisor with that email")
- if supervisor.first().name != user["supervisor_name"]:
- errors.append("Supervisor name does not match")
+ # Compare names case-insensitively and trimmed to avoid false mismatches
+ try:
+ sup_name = (supervisor.first().name or '').strip().lower()
+ posted_name = (user.get("supervisor_name") or '').strip().lower()
+ if posted_name and sup_name != posted_name:
+ errors.append("Supervisor name does not match")
+ except Exception:
+ pass
if errors:
return HttpResponse(
@@ -869,11 +887,22 @@ def accounts_bulk_create(request):
grade = UserGrades.objects.get(name=user["grade"])
user_profile.grade = grade
- if "supervisor_email" in user and "supervisor_name" in user:
- s, created = Supervisor.objects.get_or_create(
- email=user["supervisor_email"],
- name=user["supervisor_name"],
- )
+ if "supervisor_name" in user and user.get("supervisor_name"):
+ sup_email = user.get("supervisor_email")
+ # If supervisor email provided, prefer that. Otherwise try to match by name or create placeholder
+ if sup_email and sup_email != 'undefined':
+ s, created = Supervisor.objects.get_or_create(email=sup_email, defaults={"name": user.get("supervisor_name")})
+ else:
+ # try match by name
+ s_qs = Supervisor.objects.filter(name__iexact=user.get("supervisor_name"))
+ if s_qs.exists():
+ s = s_qs.first()
+ created = False
+ else:
+ import uuid
+ placeholder = f"no-email-{uuid.uuid4().hex}@local.invalid"
+ s = Supervisor.objects.create(email=placeholder, name=user.get("supervisor_name"))
+ created = True
if created:
s.save()
@@ -913,11 +942,20 @@ def accounts_bulk_create(request):
user_profile = UserProfile.objects.get(user=new_user)
user_profile.peninsula_trainee = True
# TODO: check supervisor details are correct
- if "supervisor_email" in user and "supervisor_name" in user:
- s, created = Supervisor.objects.get_or_create(
- email=user["supervisor_email"],
- name=user["supervisor_name"],
- )
+ if "supervisor_name" in user and user.get("supervisor_name"):
+ sup_email = user.get("supervisor_email")
+ if sup_email and sup_email != 'undefined':
+ s, created = Supervisor.objects.get_or_create(email=sup_email, defaults={"name": user.get("supervisor_name")})
+ else:
+ s_qs = Supervisor.objects.filter(name__iexact=user.get("supervisor_name"))
+ if s_qs.exists():
+ s = s_qs.first()
+ created = False
+ else:
+ import uuid
+ placeholder = f"no-email-{uuid.uuid4().hex}@local.invalid"
+ s = Supervisor.objects.create(email=placeholder, name=user.get("supervisor_name"))
+ created = True
if created:
s.save()
@@ -962,7 +1000,7 @@ def request_cid_details(request):
email = request.POST.get("email")
try:
validate_email(email)
- except ValidationError as e:
+ except ValidationError:
return HttpResponse("Invalid email.")
cid_users = CidUser.objects.filter(email=email)
diff --git a/templates/accounts_bulk_create.html b/templates/accounts_bulk_create.html
index 6fb4e040..34c55699 100644
--- a/templates/accounts_bulk_create.html
+++ b/templates/accounts_bulk_create.html
@@ -36,12 +36,20 @@
Please note users created this way bypass some of the validations so check details such as email addresses are correct
+
+
+
+
+
+ _="on load hide me">
@@ -67,6 +75,23 @@
// split into rows
excelRow = excelData.split(String.fromCharCode(10));
+ // If the first row looks like a header (contains words like 'user', 'email', 'grade', 'supervisor'), drop it
+ if (excelRow.length) {
+ var firstRowCols = excelRow[0].split(String.fromCharCode(9)).map(function(c){return c.trim().toLowerCase();});
+ var headerKeywords = ['user','first name','last name','email','grade','educational supervisor','supervisor','first','last'];
+ var isHeader = firstRowCols.some(function(c){
+ if (!c) return false;
+ if (headerKeywords.indexOf(c) !== -1) return true;
+ if (c.indexOf('email') !== -1) return true;
+ if (c.indexOf('supervisor') !== -1) return true;
+ return false;
+ });
+ if (isHeader) {
+ // remove header row
+ excelRow.shift();
+ }
+ }
+
// split rows into columns
for (i=0; i -1) {
+ var parts = full.split(/\s+/);
+ user.first_name = parts[0];
+ user.last_name = parts.slice(1).join(' ');
+ } else {
+ user.first_name = full;
+ user.last_name = '';
+ }
+ // supervisor email not provided in this format
+ user.supervisor_email = '';
+ }
myTbody.appendChild(myRow);
users.push(user)
emails.push(user.email)
@@ -129,8 +178,8 @@
$.post("{% url 'accounts_check_users' %}", { csrfmiddlewaretoken: "{{ csrf_token }}",
user_list: JSON.stringify(emails) }, function(data) {
- console.log("Existing users", data)
- })
+ console.log("Existing users", data)
+ })
$("#users-list").append(`${users.length} users to create/update.`)
@@ -154,23 +203,23 @@
@@ -207,6 +256,6 @@
#users-list li:has(.error) {
border: 1px solid red;
}
-
+
{% endblock content %}
\ No newline at end of file