From eac89252f954a773df4273031ac0e52829810982 Mon Sep 17 00:00:00 2001 From: Ross Date: Tue, 11 Jan 2022 19:20:20 +0000 Subject: [PATCH] . --- anatomy/static/css/anatomy.css | 16 ++- anatomy/templates/anatomy/mark.html | 25 ++-- generic/forms.py | 2 + generic/models.py | 18 ++- generic/templates/generic/group_emailed.html | 127 +++++++++++++++++-- generic/urls.py | 21 ++- generic/views.py | 33 +++-- rad/views.py | 6 +- 8 files changed, 204 insertions(+), 44 deletions(-) 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 %} +
    +
    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:

    +
    Emailing
    + + + + + + -

    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: