.
This commit is contained in:
@@ -72,6 +72,7 @@ urlpatterns = [
|
||||
),
|
||||
path("exam/<int:pk>/", views.GenericExamViews.exam_overview, name="exam_overview"),
|
||||
path("exam/<int:exam_id>/report/email", views.GenericExamViews.exam_report_email, name="exam_report_email"),
|
||||
path("exam/<int:exam_id>/report/email_unsent", views.GenericExamViews.exam_report_email_unsent, name="exam_report_email_unsent"),
|
||||
path("exam/<int:exam_id>/report/email/status", views.GenericExamViews.exam_report_email_status, name="exam_report_email_status"),
|
||||
path("exam/<int:exam_id>/report/<int:user_id>", views.GenericExamViews.exam_user_report, name="exam_user_report"),
|
||||
path("exam/<int:exam_id>/report/<int:user_id>/email", views.GenericExamViews.exam_user_report_email, name="exam_user_report_email"),
|
||||
|
||||
+6
-5
@@ -324,7 +324,7 @@ class ExamBase(models.Model):
|
||||
|
||||
return msg
|
||||
|
||||
def email_user_results(self, user, resend=False, additional_emails=list):
|
||||
def email_user_results(self, user, resend=False, additional_emails=None):
|
||||
#if self.results_email_sent and not resend:
|
||||
# return False, "Already sent."
|
||||
|
||||
@@ -332,7 +332,7 @@ class ExamBase(models.Model):
|
||||
msg = self.generate_user_report(user)
|
||||
|
||||
if not user.email:
|
||||
return False, "User has no email"
|
||||
return [False, "User has no email"]
|
||||
|
||||
emails = [user.email]
|
||||
|
||||
@@ -342,7 +342,7 @@ class ExamBase(models.Model):
|
||||
emails.append(supervisor_email)
|
||||
|
||||
|
||||
if additional_emails:
|
||||
if additional_emails is not None:
|
||||
emails.extend(additional_emails)
|
||||
|
||||
try:
|
||||
@@ -355,11 +355,11 @@ class ExamBase(models.Model):
|
||||
# html_message=html_msg,
|
||||
)
|
||||
except SMTPException as e:
|
||||
return False, e
|
||||
return [False, e]
|
||||
|
||||
#self.results_email_sent = True
|
||||
#self.save()
|
||||
return True, ""
|
||||
return [True, ""]
|
||||
|
||||
|
||||
class NoteType(models.Model):
|
||||
@@ -608,6 +608,7 @@ class CidUserExam(models.Model):
|
||||
|
||||
manual_submission = models.BooleanField(default=False)
|
||||
|
||||
# TODO switch to json field?
|
||||
results_emailed_status = models.CharField(max_length=255, blank=True)
|
||||
|
||||
|
||||
|
||||
@@ -91,6 +91,7 @@
|
||||
<summary>Email results</summary>
|
||||
User results emailed: {{exam.exam_results_emailed|default:"Never"}}<br/>
|
||||
<button id="email-results-button" title="Email results to users and their supervisors">Email user results</button>
|
||||
<button id="email-unsent-results-button" title="Email results to users and their supervisors">Email unsent user results</button>
|
||||
<button id="email-results-check-button" title="Check the status of emailed results">Check email status</button>
|
||||
<p>Note: currently only works with registered users</p>
|
||||
</details>
|
||||
@@ -116,6 +117,23 @@
|
||||
}
|
||||
evt.preventDefault();
|
||||
|
||||
})
|
||||
$("#email-unsent-results-button").click((evt) => {
|
||||
if (confirm("This will email results, please make sure scores have been refreshed before continuing")) {
|
||||
|
||||
let additional_email = prompt("Please enter an additional email to send to (user and supervisor will automatically be used if available) if required");
|
||||
|
||||
let url = "{% url exam.app_name|add:':exam_report_email_unsent' exam_id=exam.pk %}";
|
||||
|
||||
if ( additional_email != null ) {
|
||||
url = url + "?additional_email="+encodeURI(additional_email)
|
||||
}
|
||||
|
||||
window.location = url;
|
||||
|
||||
}
|
||||
evt.preventDefault();
|
||||
|
||||
})
|
||||
$("#email-results-check-button").click((evt) => {
|
||||
window.location = "{% url exam.app_name|add:':exam_report_email_status' exam_id=exam.pk %}";
|
||||
|
||||
+29
-3
@@ -560,6 +560,20 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
},
|
||||
)
|
||||
|
||||
@method_decorator(login_required)
|
||||
def exam_user(self, request, exam_id, user_id):
|
||||
exam = get_object_or_404(self.Exam.objects.prefetch_related("author"), pk=exam_id)
|
||||
|
||||
if request.user not in exam.author.all():
|
||||
if not self.check_user_access(request.user, exam_id):
|
||||
raise PermissionDenied
|
||||
|
||||
user = User.objects.get(pk=user_id)
|
||||
user_exam = exam.get_or_create_cid_user_exam(user_user=user)
|
||||
|
||||
return JsonResponse(model_to_dict(user_exam))
|
||||
|
||||
|
||||
@method_decorator(login_required)
|
||||
def exam_report_email_status(self, request, exam_id):
|
||||
exam = get_object_or_404(self.Exam.objects.prefetch_related("author"), pk=exam_id)
|
||||
@@ -578,9 +592,12 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
|
||||
return JsonResponse(status)
|
||||
|
||||
@method_decorator(login_required)
|
||||
def exam_report_email_unsent(self, request, exam_id):
|
||||
return self.exam_report_email(request, exam_id, unsent_only=True)
|
||||
|
||||
@method_decorator(login_required)
|
||||
def exam_report_email(self, request, exam_id):
|
||||
def exam_report_email(self, request, exam_id, unsent_only=False):
|
||||
exam = get_object_or_404(self.Exam.objects.prefetch_related("author"), pk=exam_id)
|
||||
|
||||
if request.user not in exam.author.all():
|
||||
@@ -606,13 +623,22 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
email_results = {}
|
||||
for u in users:
|
||||
user = User.objects.get(pk=u)
|
||||
user_exam = exam.get_or_create_cid_user_exam(user_user=user)
|
||||
|
||||
if unsent_only and user_exam.results_emailed_status:
|
||||
continue
|
||||
#print(user, user_exam.results_emailed_status)
|
||||
#if json.loads(user_exam.results_emailed_status)[0] == True:
|
||||
# continue
|
||||
|
||||
|
||||
if additional_email:
|
||||
email_results[user.username] = exam.email_user_results(user, additional_emails=[additional_email])
|
||||
else:
|
||||
email_results[user.username] = exam.email_user_results(user)
|
||||
email_results[user.username].append(f" {time}")
|
||||
user_exam.results_emailed_status = json.dumps(email_results[user.username])
|
||||
|
||||
user_exam = exam.get_or_create_cid_user_exam(user_user=user)
|
||||
user_exam.results_emailed_status = json.dumps(email_results[user.username]) + f" {time}"
|
||||
user_exam.save()
|
||||
|
||||
exam.exam_results_emailed = time
|
||||
|
||||
@@ -27,6 +27,7 @@ urlpatterns = [
|
||||
),
|
||||
path("exam/<int:pk>/", views.GenericExamViews.exam_overview, name="exam_overview"),
|
||||
path("exam/<int:exam_id>/report/email", views.GenericExamViews.exam_report_email, name="exam_report_email"),
|
||||
path("exam/<int:exam_id>/report/email_unsent", views.GenericExamViews.exam_report_email_unsent, name="exam_report_email_unsent"),
|
||||
path("exam/<int:exam_id>/report/email/status", views.GenericExamViews.exam_report_email_status, name="exam_report_email_status"),
|
||||
path("exam/<int:exam_id>/report/<int:user_id>", views.GenericExamViews.exam_user_report, name="exam_user_report"),
|
||||
path("exam/<int:exam_id>/report/<int:user_id>/email", views.GenericExamViews.exam_user_report_email, name="exam_user_report_email"),
|
||||
|
||||
@@ -72,7 +72,9 @@ urlpatterns = [
|
||||
name="exam_question_detail",
|
||||
),
|
||||
path("exam/<int:pk>/", views.GenericExamViews.exam_overview, name="exam_overview"),
|
||||
path("exam/<int:exam_id>/user/<int:user_id>", views.GenericExamViews.exam_user, name="exam_user"),
|
||||
path("exam/<int:exam_id>/report/email", views.GenericExamViews.exam_report_email, name="exam_report_email"),
|
||||
path("exam/<int:exam_id>/report/email_unsent", views.GenericExamViews.exam_report_email_unsent, name="exam_report_email_unsent"),
|
||||
path("exam/<int:exam_id>/report/email/status", views.GenericExamViews.exam_report_email_status, name="exam_report_email_status"),
|
||||
path("exam/<int:exam_id>/report/<int:user_id>", views.GenericExamViews.exam_user_report, name="exam_user_report"),
|
||||
path("exam/<int:exam_id>/report/<int:user_id>/email", views.GenericExamViews.exam_user_report_email, name="exam_user_report_email"),
|
||||
|
||||
@@ -27,6 +27,7 @@ urlpatterns = [
|
||||
),
|
||||
path("exam/<int:pk>/", views.GenericExamViews.exam_overview, name="exam_overview"),
|
||||
path("exam/<int:exam_id>/report/email", views.GenericExamViews.exam_report_email, name="exam_report_email"),
|
||||
path("exam/<int:exam_id>/report/email_unsent", views.GenericExamViews.exam_report_email_unsent, name="exam_report_email_unsent"),
|
||||
path("exam/<int:exam_id>/report/email/status", views.GenericExamViews.exam_report_email_status, name="exam_report_email_status"),
|
||||
path("exam/<int:exam_id>/report/<int:user_id>", views.GenericExamViews.exam_user_report, name="exam_user_report"),
|
||||
path("exam/<int:exam_id>/report/<int:user_id>/email", views.GenericExamViews.exam_user_report_email, name="exam_user_report_email"),
|
||||
|
||||
Reference in New Issue
Block a user