diff --git a/anatomy/urls.py b/anatomy/urls.py index b560e040..acc781f6 100644 --- a/anatomy/urls.py +++ b/anatomy/urls.py @@ -72,6 +72,7 @@ urlpatterns = [ ), path("exam//", views.GenericExamViews.exam_overview, name="exam_overview"), path("exam//report/email", views.GenericExamViews.exam_report_email, name="exam_report_email"), + path("exam//report/email_unsent", views.GenericExamViews.exam_report_email_unsent, name="exam_report_email_unsent"), path("exam//report/email/status", views.GenericExamViews.exam_report_email_status, name="exam_report_email_status"), path("exam//report/", views.GenericExamViews.exam_user_report, name="exam_user_report"), path("exam//report//email", views.GenericExamViews.exam_user_report_email, name="exam_user_report_email"), diff --git a/generic/models.py b/generic/models.py index 28c261db..6b58d2ac 100644 --- a/generic/models.py +++ b/generic/models.py @@ -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) diff --git a/generic/templates/generic/exam_scores_base.html b/generic/templates/generic/exam_scores_base.html index 91290a67..13e60698 100644 --- a/generic/templates/generic/exam_scores_base.html +++ b/generic/templates/generic/exam_scores_base.html @@ -91,6 +91,7 @@ Email results User results emailed: {{exam.exam_results_emailed|default:"Never"}}
+

Note: currently only works with registered users

@@ -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 %}"; diff --git a/generic/views.py b/generic/views.py index 885ec813..de6ac648 100644 --- a/generic/views.py +++ b/generic/views.py @@ -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 diff --git a/physics/urls.py b/physics/urls.py index daef603f..2f5642f4 100644 --- a/physics/urls.py +++ b/physics/urls.py @@ -27,6 +27,7 @@ urlpatterns = [ ), path("exam//", views.GenericExamViews.exam_overview, name="exam_overview"), path("exam//report/email", views.GenericExamViews.exam_report_email, name="exam_report_email"), + path("exam//report/email_unsent", views.GenericExamViews.exam_report_email_unsent, name="exam_report_email_unsent"), path("exam//report/email/status", views.GenericExamViews.exam_report_email_status, name="exam_report_email_status"), path("exam//report/", views.GenericExamViews.exam_user_report, name="exam_user_report"), path("exam//report//email", views.GenericExamViews.exam_user_report_email, name="exam_user_report_email"), diff --git a/rapids/urls.py b/rapids/urls.py index 29608510..df6328c2 100755 --- a/rapids/urls.py +++ b/rapids/urls.py @@ -72,7 +72,9 @@ urlpatterns = [ name="exam_question_detail", ), path("exam//", views.GenericExamViews.exam_overview, name="exam_overview"), + path("exam//user/", views.GenericExamViews.exam_user, name="exam_user"), path("exam//report/email", views.GenericExamViews.exam_report_email, name="exam_report_email"), + path("exam//report/email_unsent", views.GenericExamViews.exam_report_email_unsent, name="exam_report_email_unsent"), path("exam//report/email/status", views.GenericExamViews.exam_report_email_status, name="exam_report_email_status"), path("exam//report/", views.GenericExamViews.exam_user_report, name="exam_user_report"), path("exam//report//email", views.GenericExamViews.exam_user_report_email, name="exam_user_report_email"), diff --git a/sbas/urls.py b/sbas/urls.py index f25dd7be..6bfa901c 100644 --- a/sbas/urls.py +++ b/sbas/urls.py @@ -27,6 +27,7 @@ urlpatterns = [ ), path("exam//", views.GenericExamViews.exam_overview, name="exam_overview"), path("exam//report/email", views.GenericExamViews.exam_report_email, name="exam_report_email"), + path("exam//report/email_unsent", views.GenericExamViews.exam_report_email_unsent, name="exam_report_email_unsent"), path("exam//report/email/status", views.GenericExamViews.exam_report_email_status, name="exam_report_email_status"), path("exam//report/", views.GenericExamViews.exam_user_report, name="exam_user_report"), path("exam//report//email", views.GenericExamViews.exam_user_report_email, name="exam_user_report_email"),