diff --git a/lib/cadet/assessments/assessments.ex b/lib/cadet/assessments/assessments.ex index 7203d4e4b..49f2c6451 100644 --- a/lib/cadet/assessments/assessments.ex +++ b/lib/cadet/assessments/assessments.ex @@ -1549,6 +1549,66 @@ defmodule Cadet.Assessments do ) end + def get_ungraded_submission_for_email_notification(avenger_cr) do + submission_answers_query = + Answer + |> group_by([ans], ans.submission_id) + |> select([ans], %{ + submission_id: ans.submission_id, + graded_count: filter(count(ans.id), not is_nil(ans.grader_id)) + }) + + question_answers_query = + Question + |> group_by([q], q.assessment_id) + |> join(:left, [q], asst in assoc(q, :assessment)) + |> select([q, asst], %{assessment_id: q.assessment_id, question_count: count(q.id)}) + + student_query = + CourseRegistration + |> join(:inner, [cr], g in assoc(cr, :group)) + |> where([cr, g], g.leader_id == ^avenger_cr.id) + |> select([cr, _], cr.id) + + submissions = + Submission + |> join(:inner, [s], ans in subquery(submission_answers_query), + on: s.id == ans.submission_id + ) + |> join(:inner, [s, ans], asst in subquery(question_answers_query), + on: s.assessment_id == asst.assessment_id + ) + |> where([s, _, _], s.status == "submitted") + |> where([_, ans, asst], asst.question_count > ans.graded_count) + |> where( + [s, _, _], + s.student_id in subquery(student_query) or s.student_id == ^avenger_cr.id + ) + |> select([s, _, _], %{id: s.id, student_id: s.student_id, assessment_id: s.assessment_id}) + |> Repo.all() + + formatted_submissions = + Enum.map(submissions, fn submission -> + [student_course_id, student_name] = + CourseRegistration + |> join(:inner, [cr], u in assoc(cr, :user)) + |> where([cr], cr.id == ^submission.student_id) + |> select([cr, u], [cr.course_id, u.name]) + |> Repo.one() + + assessment_title = Repo.get(Assessment, submission.assessment_id).title + + %{ + student_name: student_name, + student_course_id: student_course_id, + assessment_title: assessment_title, + submission_id: submission.id + } + end) + + {:ok, formatted_submissions} + end + defp generate_grading_summary_view_model(submissions, course_id) do users = CourseRegistration diff --git a/lib/cadet/email.ex b/lib/cadet/email.ex index b7ff08101..18a6ff357 100644 --- a/lib/cadet/email.ex +++ b/lib/cadet/email.ex @@ -9,6 +9,18 @@ defmodule Cadet.Email do if is_nil(avenger.email) do nil else + ungraded_submissions = + Enum.map(ungraded_submissions, fn submission -> + Map.put( + submission, + :submission_url, + build_submission_url( + submission[:student_course_id], + submission[:submission_id] + ) + ) + end) + base_email() |> to(avenger.email) |> assign(:avenger_name, avenger.name) @@ -22,11 +34,18 @@ defmodule Cadet.Email do if is_nil(avenger.email) do nil else + submission = + Map.put( + submission, + :submission_url, + build_submission_url(submission.assessment.course_id, submission.id) + ) + base_email() |> to(avenger.email) |> assign(:avenger_name, avenger.name) |> assign(:student_name, student.name) - |> assign(:assessment_title, submission.assessment.title) + |> assign(:submission, submission) |> subject("New submission for #{submission.assessment.title}") |> render("#{template_file_name}.html") end @@ -37,4 +56,9 @@ defmodule Cadet.Email do |> from("noreply@sourceacademy.org") |> put_html_layout({CadetWeb.LayoutView, "email.html"}) end + + # TODO update this to use frontend url + defp build_submission_url(course_id, submission_id) do + "https://sourceacademy.org/courses/#{course_id}/grading/#{submission_id}" + end end diff --git a/lib/cadet/workers/NotificationWorker.ex b/lib/cadet/workers/NotificationWorker.ex index 67913a033..c4576ffc1 100644 --- a/lib/cadet/workers/NotificationWorker.ex +++ b/lib/cadet/workers/NotificationWorker.ex @@ -73,11 +73,8 @@ defmodule Cadet.Workers.NotificationWorker do for avenger_cr <- avengers_crs do avenger = Cadet.Accounts.get_user(avenger_cr.user_id) - {:ok, %{data: %{submissions: ungraded_submissions}}} = - Cadet.Assessments.submissions_by_grader_for_index(avenger_cr, %{ - "group" => "true", - "notFullyGraded" => "true" - }) + {:ok, ungraded_submissions} = + Cadet.Assessments.get_ungraded_submission_for_email_notification(avenger_cr) if Enum.count(ungraded_submissions) < ungraded_threshold do IO.puts("[AVENGER_BACKLOG] below threshold!") diff --git a/lib/cadet_web/templates/email/assessment_submission.html.eex b/lib/cadet_web/templates/email/assessment_submission.html.eex index 240c72dcd..21ecb7791 100644 --- a/lib/cadet_web/templates/email/assessment_submission.html.eex +++ b/lib/cadet_web/templates/email/assessment_submission.html.eex @@ -1,5 +1,5 @@
Dear <%= @avenger_name %>,
-There is a new submission by <%= @student_name %> for <%= @assessment_title %>. Please Review and grade the submission
+There is a new submission by <%= @student_name %> for <%= @submission.assessment.title %>. Please Review and grade the submission.
Unsubscribe from this email topic. diff --git a/lib/cadet_web/templates/email/avenger_backlog.html.eex b/lib/cadet_web/templates/email/avenger_backlog.html.eex index 1bd59d74b..094619143 100644 --- a/lib/cadet_web/templates/email/avenger_backlog.html.eex +++ b/lib/cadet_web/templates/email/avenger_backlog.html.eex @@ -3,7 +3,7 @@ You have ungraded submissions. Please review and grade the following submissions as soon as possible. <%= for s <- @submissions do %> -<%= s["assessment"]["title"] %> by <%= s["student"]["name"]%>
+<%= s[:assessment_title] %> by <%= s[:student_name] %>
<% end %> Unsubscribe from this email topic. diff --git a/test/cadet/email_test.exs b/test/cadet/email_test.exs index e7c1ec3e6..f61a9e72c 100644 --- a/test/cadet/email_test.exs +++ b/test/cadet/email_test.exs @@ -24,11 +24,8 @@ defmodule Cadet.EmailTest do avenger_user = insert(:user, %{email: "test@gmail.com"}) avenger = insert(:course_registration, %{user: avenger_user, role: :staff}) - {:ok, %{data: %{submissions: ungraded_submissions}}} = - Cadet.Assessments.submissions_by_grader_for_index(avenger, %{ - "group" => "true", - "ungradedOnly" => "true" - }) + {:ok, ungraded_submissions} = + Cadet.Assessments.get_ungraded_submission_for_email_notification(avenger) email = Email.avenger_backlog_email("avenger_backlog", avenger_user, ungraded_submissions) diff --git a/test/cadet/jobs/notification_worker/notification_worker_test.exs b/test/cadet/jobs/notification_worker/notification_worker_test.exs index 9368a033c..49e772873 100644 --- a/test/cadet/jobs/notification_worker/notification_worker_test.exs +++ b/test/cadet/jobs/notification_worker/notification_worker_test.exs @@ -18,11 +18,8 @@ defmodule Cadet.NotificationWorker.NotificationWorkerTest do submission = List.first(List.first(data.mcq_answers)).submission # setup for avenger backlog - {:ok, %{data: %{submissions: ungraded_submissions}}} = - Cadet.Assessments.submissions_by_grader_for_index(avenger_cr, %{ - "group" => "true", - "notFullyGraded" => "true" - }) + {:ok, ungraded_submissions} = + Cadet.Assessments.get_ungraded_submission_for_email_notification(avenger_cr) Repo.update_all(NotificationType, set: [is_enabled: true]) Repo.update_all(NotificationConfig, set: [is_enabled: true]) @@ -41,6 +38,7 @@ defmodule Cadet.NotificationWorker.NotificationWorkerTest do perform_job(NotificationWorker, %{"notification_type" => "avenger_backlog"}) avenger_email = avenger_user.email + assert_delivered_email_matches(%{to: [{_, ^avenger_email}]}) end diff --git a/test/support/seeds.ex b/test/support/seeds.ex index e88ec7f21..1603f3d3e 100644 --- a/test/support/seeds.ex +++ b/test/support/seeds.ex @@ -180,7 +180,9 @@ defmodule Cadet.Test.Seeds do submissions = students |> Enum.take(2) - |> Enum.map(&insert(:submission, %{assessment: assessment, student: &1})) + |> Enum.map( + &insert(:submission, %{assessment: assessment, student: &1, status: :submitted}) + ) # Programming Answers programming_answers =