diff --git a/anatomy/static/css/anatomy.css b/anatomy/static/css/anatomy.css
index 1ffe22ea..510ce10a 100644
--- a/anatomy/static/css/anatomy.css
+++ b/anatomy/static/css/anatomy.css
@@ -805,14 +805,26 @@ input {
.view-finding-button {
flex: 1;
}
+
.view-finding-details {
flex: 4;
}
-.delete-finding-link, .edit-finding-link {
+.delete-finding-link,
+.edit-finding-link {
flex: 1;
}
-summary h2, summary h3, summary h4, summary h5 {
+summary h2,
+summary h3,
+summary h4,
+summary h5 {
display: inline;
+}
+
+.mark-buttons {
+ position: sticky;
+ bottom: 0px;
+ background-color: black;
+ opacity: 80%;
}
\ No newline at end of file
diff --git a/anatomy/templates/anatomy/mark.html b/anatomy/templates/anatomy/mark.html
index 6e625421..8562ce48 100644
--- a/anatomy/templates/anatomy/mark.html
+++ b/anatomy/templates/anatomy/mark.html
@@ -36,17 +36,20 @@
{{ answer }}
{% endfor %}
- Key: 2 Marks, 1
- Mark, 0 Marks
- {% if question_details.current > 1 %}
-
- {% endif %}
-
- {% if question_details.current >= question_details.total %}
- {% else %}
-
-
- {% endif %}
+
{{ form.as_p }}
diff --git a/generic/forms.py b/generic/forms.py
index 98378588..b2077a27 100755
--- a/generic/forms.py
+++ b/generic/forms.py
@@ -143,4 +143,6 @@ class CidUserForm(ModelForm):
"name",
"email",
"supervisor_email",
+ "login_email_sent",
+ "results_email_sent",
]
diff --git a/generic/models.py b/generic/models.py
index 3c25b8d4..d5873ac6 100644
--- a/generic/models.py
+++ b/generic/models.py
@@ -312,7 +312,7 @@ class CidUser(models.Model):
for n, t in self.EXAM_TYPES:
exam_rel = getattr(self, t)
if exam_rel.exists():
- exams = exam_rel.filter(exam_mode=True).order_by("name")
+ exams = exam_rel.filter(exam_mode=True, archive=False).order_by("name")
available_exams.append((n, exams))
return available_exams
@@ -324,28 +324,33 @@ class CidUser(models.Model):
if self.name:
name = f"{self.name} "
- exam_text = [f"Candidate {name}{self.cid} [{self.email}]"]
+ exam_text = [f"Candidate {self.cid} {name}[{self.email}]"]
for exam_type, exams in exam_list:
exam_text.append(f"{'='*len(exam_type)}\n{exam_type}\n{'='*len(exam_type)}")
for exam in exams:
- print(exam)
try:
user_score = exam.user_scores[str(self.cid)]
except KeyError:
user_score = "Score not generated"
t = exam.get_exam_stats()
+ try:
+ percentage = (
+ f" ({user_score / int(exam.stats_max_possible) * 100:.2f}%)"
+ )
+ except TypeError:
+ percentage = ""
+
exam_text.append(
f"""{t}
-# Score: {user_score} / {int(exam.stats_max_possible)}
+# Score: {user_score} / {int(exam.stats_max_possible)}{percentage}
"""
)
msg = "\n\n".join(exam_text)
- print(msg)
return msg
html_msg = f""""""
@@ -430,6 +435,9 @@ class CidUser(models.Model):
self.save()
return True, ""
+ def get_email_results_url(self):
+ return reverse("generic:candidate_email_results", kwargs={"cid": self.cid})
+
class CidUserExam(models.Model):
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
diff --git a/generic/templates/generic/group_emailed.html b/generic/templates/generic/group_emailed.html
index 81df8361..1f3c4ea0 100755
--- a/generic/templates/generic/group_emailed.html
+++ b/generic/templates/generic/group_emailed.html
@@ -1,15 +1,124 @@
{% extends 'generic/base.html' %}
{% block content %}
- Attempted to send {{users_count}} emails.
+ {{users_count}} emails to send.
+
+ Emails to send:
+
+
+ {% for user in users %}
+ - {{user.cid}}/{{user.name}}: {{user.email}} [{{user.supervisor_email}}]
+ {% endfor %}
+
+
+
+
+
+
- Emails sent:
- {% for u in sent %}
- {{u.cid}}: {{u.email}}
- {% endfor %}
- Emails not sent:
- {% for u, msg in not_sent %}
- {{u.cid}}: {{u.email}} [{{msg}}]
- {% endfor %}
{% endblock %}
diff --git a/generic/urls.py b/generic/urls.py
index d785aacb..d605c3a5 100755
--- a/generic/urls.py
+++ b/generic/urls.py
@@ -26,12 +26,27 @@ urlpatterns = [
),
name="examination-autocomplete",
),
- path("cids/manage//update", views.CidUserUpdate.as_view(), name="update_cid"),
+ path(
+ "cids/manage//update", views.CidUserUpdate.as_view(), name="update_cid"
+ ),
+ path(
+ "cids/manage//email_results",
+ views.candidate_email_results,
+ name="candidate_email_results",
+ ),
path("cids/manage/", views.CidUserView.as_view(), name="manage_cids"),
path("cids/manage/exams", views.CidUserExamView.as_view(), name="manage_cid_exams"),
path("cids/group/", views.group_view, name="group_view"),
path("cids/group//email", views.group_email, name="group_email"),
- path("cids/group//email_results", views.group_email_results, name="group_email_results"),
- path("cids/group//email/resend", views.group_email_resend, name="group_email_resend"),
+ path(
+ "cids/group//email_results",
+ views.group_email_results,
+ name="group_email_results",
+ ),
+ path(
+ "cids/group//email/resend",
+ views.group_email_resend,
+ name="group_email_resend",
+ ),
path("cids/create", views.manage_cid_users, name="manage_cid_users"),
]
diff --git a/generic/views.py b/generic/views.py
index dbca2880..3eaba739 100644
--- a/generic/views.py
+++ b/generic/views.py
@@ -1415,31 +1415,40 @@ def group_email(request, pk, resend=False):
)
-@login_required
@user_is_cid_user_manager
def group_email_results(request, pk, resend=False):
group = get_object_or_404(CidUserGroup, pk=pk)
if resend:
- users = group.ciduser_set.filter()
+ users = group.ciduser_set.filter(internal_candidate=True)
else:
- users = group.ciduser_set.filter(results_email_sent=False)
+ users = group.ciduser_set.filter(internal_candidate=True, results_email_sent=False)
- sent = []
- not_sent = []
- for u in users:
- success, msg = u.email_results(resend=resend)
- if success:
- sent.append(u)
- else:
- not_sent.append((u, msg))
+ #sent = []
+ #not_sent = []
+ #for u in users:
+ # success, msg = u.email_results(resend=resend)
+ # if success:
+ # sent.append(u)
+ # else:
+ # not_sent.append((u, msg))
return render(
request,
"generic/group_emailed.html",
- {"sent": sent, "not_sent": not_sent, "users_count": users.count()},
+ #{"sent": sent, "not_sent": not_sent, "users_count": users.count()},
+ {"users": users, "users_count": users.count()},
)
+@user_is_cid_user_manager
+def candidate_email_results(request, cid, resend=False):
+ user = CidUser.objects.get(cid=cid)
+
+ email_sent, comment = user.email_results()
+
+ return JsonResponse({"sent": email_sent, "comment": comment})
+
+
@login_required
@user_is_cid_user_manager
diff --git a/rad/views.py b/rad/views.py
index 1e571c2b..6e91eea4 100644
--- a/rad/views.py
+++ b/rad/views.py
@@ -1,3 +1,4 @@
+from generic.decorators import user_is_cid_user_manager
from generic.views import get_question_and_content_type
from django.core.exceptions import PermissionDenied
from django.shortcuts import render, get_object_or_404, redirect
@@ -85,7 +86,8 @@ def cid_scores_admin(request, cid):
@login_required
-@user_passes_test(lambda u: u.is_superuser)
+#@user_passes_test(lambda u: u.is_superuser)
+@user_is_cid_user_manager
def cid_results(request, cid):
cid_user = CidUser.objects.filter(cid=cid).first()
@@ -122,7 +124,7 @@ def cid_scores(request, pk, passcode):
"longs": (LongsCidUserAnswer, LongsExam),
"sbas": (SbasCidUserAnswer, SbasExam),
}
- kwargs = {"exam_mode": True}
+ kwargs = {"exam_mode": True, "archive": False}
exams = []
for exam_type in EXAM_ANSWER_MAP: