From 9682fbb49cb14fff1d011b7fb41fa589e445e631 Mon Sep 17 00:00:00 2001 From: endoooo Date: Wed, 19 Jun 2024 06:17:49 -0300 Subject: [PATCH 1/5] fix: added guards to prevent `<.assessment_point_entry_preview>` crash resolves #181 --- .../components/reporting_components.ex | 14 ++++++++++---- .../id/student_report_card_live.html.heex | 4 +++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/lib/lanttern_web/components/reporting_components.ex b/lib/lanttern_web/components/reporting_components.ex index 38d3c0f4..5eef3ef0 100644 --- a/lib/lanttern_web/components/reporting_components.ex +++ b/lib/lanttern_web/components/reporting_components.ex @@ -11,6 +11,7 @@ defmodule LantternWeb.ReportingComponents do import Lanttern.SupabaseHelpers, only: [object_url_to_render_url: 2] alias Lanttern.Assessments.AssessmentPointEntry + alias Lanttern.Grading.OrdinalValue alias Lanttern.Grading.Scale alias Lanttern.Reporting.ReportCard alias Lanttern.Rubrics.Rubric @@ -219,12 +220,12 @@ defmodule LantternWeb.ReportingComponents do required: true, doc: "Requires `scale` and `ordinal_value` preloads" - # attr :scale, Scale, required: true, doc: "Requires `ordinal_values` preload" - # attr :rubric, Rubric, default: nil, doc: "Requires `descriptors` preload" attr :id, :string, default: nil attr :class, :any, default: nil - def assessment_point_entry_preview(%{entry: %{scale: %{type: "ordinal"}}} = assigns) do + def assessment_point_entry_preview( + %{entry: %{ordinal_value: %OrdinalValue{}, scale: %{type: "ordinal"}}} = assigns + ) do ~H""" <.ordinal_value_badge ordinal_value={@entry.ordinal_value} class={@class} id={@id}> <%= String.slice(@entry.ordinal_value.name, 0..2) %> @@ -232,7 +233,10 @@ defmodule LantternWeb.ReportingComponents do """ end - def assessment_point_entry_preview(%{entry: %{scale: %{type: "numeric"}}} = assigns) do + def assessment_point_entry_preview( + %{entry: %{score: score, scale: %{type: "numeric"}}} = assigns + ) + when not is_nil(score) do ~H""" <.badge class={@class} id={@id}> <%= @entry.score %> @@ -240,6 +244,8 @@ defmodule LantternWeb.ReportingComponents do """ end + def assessment_point_entry_preview(_assigns), do: nil + attr :footnote, :string, required: true attr :class, :any, default: nil diff --git a/lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex b/lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex index fddaff33..e528b918 100644 --- a/lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex +++ b/lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex @@ -49,7 +49,9 @@ > <:bottom_content :if={entries != []}>
- <.assessment_point_entry_preview :for={entry <- entries} entry={entry} /> + <%= for entry <- entries, entry.ordinal_value || entry.score do %> + <.assessment_point_entry_preview entry={entry} /> + <% end %>
From 249432d5ef2698e30431287733bc67a8b60fc2f9 Mon Sep 17 00:00:00 2001 From: endoooo Date: Wed, 19 Jun 2024 14:09:50 -0300 Subject: [PATCH 2/5] chore: adjusted grade report calcultion function to prevent manual grading overwriting - added a new `:updated_with_manual` key to `batch_calculation_results` type - added support to `:force_overwrite` opt in `calculate_student_grade/5` - adjusted calculation in `calculate_student_grade/5`, `calculate_student_grades/3`, `calculate_subject_grades/4`, and `calculate_cycle_grades/3` --- lib/lanttern/grades_reports.ex | 64 ++- .../id/students_grades_component.ex | 11 + test/lanttern/grades_reports_test.exs | 401 +++++++++++++++--- 3 files changed, 413 insertions(+), 63 deletions(-) diff --git a/lib/lanttern/grades_reports.ex b/lib/lanttern/grades_reports.ex index eb8bb156..56b41dc2 100644 --- a/lib/lanttern/grades_reports.ex +++ b/lib/lanttern/grades_reports.ex @@ -521,22 +521,30 @@ defmodule Lanttern.GradesReports do Uses a third elemente in the `:ok` returned tuple: - `:created` when the `StudentGradeReportEntry` is created - `:updated` when the `StudentGradeReportEntry` is updated + - `:updated_with_manual` when the `StudentGradeReportEntry` is updated, except from manually adjusted `ordinal_value_id` or `score` - `:deleted` when the `StudentGradeReportEntry` is deleted (always `nil` in the second element) - `:noop` when the nothing is created, updated, or deleted (always `nil` in the second element) + + ### Options + + - `:force_overwrite` - ignore the update with manual rule, and overwrite grade if needed """ @spec calculate_student_grade( student_id :: integer(), grades_report_id :: integer(), grades_report_cycle_id :: integer(), - grades_report_subject_id :: integer() + grades_report_subject_id :: integer(), + Keyword.t() ) :: - {:ok, StudentGradeReportEntry.t() | nil, :created | :updated | :deleted | :noop} + {:ok, StudentGradeReportEntry.t() | nil, + :created | :updated | :updated_keep_manual | :deleted | :noop} | {:error, Ecto.Changeset.t()} def calculate_student_grade( student_id, grades_report_id, grades_report_cycle_id, - grades_report_subject_id + grades_report_subject_id, + opts \\ [] ) do # get grades report scale %{scale: scale} = get_grades_report!(grades_report_id, preloads: :scale) @@ -569,17 +577,29 @@ defmodule Lanttern.GradesReports do grades_report_id, grades_report_cycle_id, grades_report_subject_id, - scale + scale, + opts ) end + defp handle_student_grades_report_entry_creation( + entries_and_grade_components, + student_id, + grades_report_id, + grades_report_cycle_id, + grades_report_subject_id, + scale, + opts \\ [] + ) + defp handle_student_grades_report_entry_creation( [], student_id, _grades_report_id, grades_report_cycle_id, grades_report_subject_id, - _scale + _scale, + _opts ) do # delete existing student grade report entry if needed Repo.get_by(StudentGradeReportEntry, @@ -605,7 +625,8 @@ defmodule Lanttern.GradesReports do grades_report_id, grades_report_cycle_id, grades_report_subject_id, - scale + scale, + opts ) do {normalized_avg, composition} = calculate_weighted_avg_and_build_comp_metadata(entries_and_grade_components) @@ -637,6 +658,12 @@ defmodule Lanttern.GradesReports do composition_datetime: DateTime.utc_now() }) + force_overwrite = + case Keyword.get(opts, :force_overwrite) do + true -> true + _ -> false + end + # create or update existing student grade report entry Repo.get_by(StudentGradeReportEntry, student_id: student_id, @@ -650,6 +677,24 @@ defmodule Lanttern.GradesReports do error_tuple -> error_tuple end + %{ordinal_value_id: ov_id, composition_ordinal_value_id: comp_ov_id} = sgre + when ov_id != comp_ov_id and not force_overwrite -> + attrs = Map.drop(attrs, [:ordinal_value_id]) + + case update_student_grade_report_entry(sgre, attrs) do + {:ok, sgre} -> {:ok, sgre, :updated_with_manual} + error_tuple -> error_tuple + end + + %{score: score, composition_score: comp_score} = sgre + when score != comp_score and not force_overwrite -> + attrs = Map.drop(attrs, [:score]) + + case update_student_grade_report_entry(sgre, attrs) do + {:ok, sgre} -> {:ok, sgre, :updated_with_manual} + error_tuple -> error_tuple + end + sgre -> case update_student_grade_report_entry(sgre, attrs) do {:ok, sgre} -> {:ok, sgre, :updated} @@ -724,6 +769,7 @@ defmodule Lanttern.GradesReports do @type batch_calculation_results() :: %{ created: integer(), updated: integer(), + updated_with_manual: integer(), deleted: integer(), noop: integer() } @@ -800,7 +846,7 @@ defmodule Lanttern.GradesReports do grades_report_id, grades_report_cycle_id, scale, - results \\ %{created: 0, updated: 0, deleted: 0, noop: 0} + results \\ %{created: 0, updated: 0, updated_with_manual: 0, deleted: 0, noop: 0} ) defp handle_grades_report_subject_entries_and_grade_components( @@ -922,7 +968,7 @@ defmodule Lanttern.GradesReports do grades_report_cycle_id, grades_report_subject_id, scale, - results \\ %{created: 0, updated: 0, deleted: 0, noop: 0} + results \\ %{created: 0, updated: 0, updated_with_manual: 0, deleted: 0, noop: 0} ) defp handle_students_entries_and_grade_components( @@ -1051,7 +1097,7 @@ defmodule Lanttern.GradesReports do grades_report_id, grades_report_cycle_id, scale, - results \\ %{created: 0, updated: 0, deleted: 0, noop: 0} + results \\ %{created: 0, updated: 0, updated_with_manual: 0, deleted: 0, noop: 0} ) defp handle_students_grades_report_subjects_entries_and_grade_components( diff --git a/lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex b/lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex index a5bab337..493b68d5 100644 --- a/lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex +++ b/lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex @@ -427,6 +427,17 @@ defmodule LantternWeb.ReportCardLive.StudentsGradesComponent do build_calculation_results_message(results, [msg | msgs]) end + defp build_calculation_results_message([{:updated_with_manual, count} | results], msgs) do + msg = + ngettext( + "1 grade composition updated (manual grade not changed)", + "%{count} grades compositions updated (manual grades not changed)", + count + ) + + build_calculation_results_message(results, [msg | msgs]) + end + defp build_calculation_results_message([{:deleted, count} | results], msgs) do msg = ngettext("1 grade removed", "%{count} grades removed", count) build_calculation_results_message(results, [msg | msgs]) diff --git a/test/lanttern/grades_reports_test.exs b/test/lanttern/grades_reports_test.exs index 391c437e..59209b68 100644 --- a/test/lanttern/grades_reports_test.exs +++ b/test/lanttern/grades_reports_test.exs @@ -1011,7 +1011,7 @@ defmodule Lanttern.GradesReportsTest do student_id: ^expected_std_id, composition_normalized_value: 0.56667, ordinal_value_id: ^expected_ov_id - }, + } = sgre_3, :created} = GradesReports.calculate_student_grade( std_3.id, @@ -1037,6 +1037,47 @@ defmodule Lanttern.GradesReportsTest do grades_report_subject.id ) + # UPDATE MANUALLY CHANGED GRADE CASE + # when calculating for an existing student/cycle/subject + # with manual grading, update the composition but not the grade + + GradesReports.update_student_grade_report_entry(sgre_3, %{ordinal_value_id: ov_c.id}) + expected_manual_ov_id = ov_c.id + + assert {:ok, + %StudentGradeReportEntry{ + id: ^sgre_3_id, + student_id: ^expected_std_id, + composition_normalized_value: 0.56667, + ordinal_value_id: ^expected_manual_ov_id + }, + :updated_with_manual} = + GradesReports.calculate_student_grade( + std_3.id, + grades_report.id, + grades_report_cycle.id, + grades_report_subject.id + ) + + # UPDATE MANUALLY CHANGED GRADE CASE WITH force_overwrite opt + # same as above, but do change the ordinal value + + assert {:ok, + %StudentGradeReportEntry{ + id: ^sgre_3_id, + student_id: ^expected_std_id, + composition_normalized_value: 0.56667, + ordinal_value_id: ^expected_ov_id + }, + :updated} = + GradesReports.calculate_student_grade( + std_3.id, + grades_report.id, + grades_report_cycle.id, + grades_report_subject.id, + force_overwrite: true + ) + # UPDATE + EMPTY CASE # when calculating for an existing student/cycle/subject, # that is now empty, delete the entry @@ -1085,13 +1126,16 @@ defmodule Lanttern.GradesReportsTest do # compositions (same for each subject): ap1 = w1, ap2 = w2, ap3 = w3 # # test cases (in ap order) - # exc - ach - pro = 0.75000 = C (actually irrelevant, will be delete to test update + no entries case) - # eme - ach - exc = 0.85000 = B - # eme - eme - eme = 0.40000 = E + # 1 exc - ach - pro = 0.75000 = C (actually irrelevant, will be delete to test update + no entries case) + # 2 eme - ach - exc = 0.85000 = B + # 3 eme - eme - eme = 0.40000 = E + # 4 eme - eme - eme = 0.40000 = C (view update manual grade below) # - # no entries case: there's a 4th subject without entries. it should return nil - # update case: subject 3 will be pre calculated. the function should update the std grade report entry - # update + no entries case: when there's no entries but an existing student grades report entry, delete it + # 1 update + no entries case: when there's no entries but an existing student grades report entry, delete it + # 2 create + # 3 update case: subject 3 will be pre calculated. the function should update the std grade report entry + # 4 update manual grade: when the current grade is different from the composition/calculated one, update but keep manual grade + # 5 no entries case: there's a 5th subject without entries. it should return nil marking_scale = GradingFixtures.scale_fixture(%{type: "ordinal"}) @@ -1122,7 +1166,7 @@ defmodule Lanttern.GradesReportsTest do normalized_value: 0.85 }) - _ov_c = + ov_c = GradingFixtures.ordinal_value_fixture(%{scale_id: grading_scale.id, normalized_value: 0.7}) _ov_d = @@ -1134,6 +1178,7 @@ defmodule Lanttern.GradesReportsTest do strand_1 = LearningContextFixtures.strand_fixture() strand_2 = LearningContextFixtures.strand_fixture() strand_3 = LearningContextFixtures.strand_fixture() + strand_4 = LearningContextFixtures.strand_fixture() goal_1_1 = AssessmentsFixtures.assessment_point_fixture(%{ @@ -1189,10 +1234,29 @@ defmodule Lanttern.GradesReportsTest do scale_id: marking_scale.id }) + goal_4_1 = + AssessmentsFixtures.assessment_point_fixture(%{ + strand_id: strand_4.id, + scale_id: marking_scale.id + }) + + goal_4_2 = + AssessmentsFixtures.assessment_point_fixture(%{ + strand_id: strand_4.id, + scale_id: marking_scale.id + }) + + goal_4_3 = + AssessmentsFixtures.assessment_point_fixture(%{ + strand_id: strand_4.id, + scale_id: marking_scale.id + }) + subject_1 = TaxonomyFixtures.subject_fixture() subject_2 = TaxonomyFixtures.subject_fixture() subject_3 = TaxonomyFixtures.subject_fixture() subject_4 = TaxonomyFixtures.subject_fixture() + subject_5 = TaxonomyFixtures.subject_fixture() cycle = SchoolsFixtures.cycle_fixture() grades_report = grades_report_fixture(%{scale_id: grading_scale.id}) @@ -1226,6 +1290,12 @@ defmodule Lanttern.GradesReportsTest do grades_report_id: grades_report.id }) + grades_report_subject_5 = + grades_report_subject_fixture(%{ + subject_id: subject_5.id, + grades_report_id: grades_report.id + }) + _grade_component_1_1 = GradingFixtures.grade_component_fixture(%{ grades_report_id: grades_report.id, @@ -1307,6 +1377,33 @@ defmodule Lanttern.GradesReportsTest do weight: 3.0 }) + _grade_component_4_1 = + GradingFixtures.grade_component_fixture(%{ + grades_report_id: grades_report.id, + grades_report_cycle_id: grades_report_cycle.id, + grades_report_subject_id: grades_report_subject_4.id, + assessment_point_id: goal_4_1.id, + weight: 1.0 + }) + + _grade_component_4_2 = + GradingFixtures.grade_component_fixture(%{ + grades_report_id: grades_report.id, + grades_report_cycle_id: grades_report_cycle.id, + grades_report_subject_id: grades_report_subject_4.id, + assessment_point_id: goal_4_2.id, + weight: 2.0 + }) + + _grade_component_4_3 = + GradingFixtures.grade_component_fixture(%{ + grades_report_id: grades_report.id, + grades_report_cycle_id: grades_report_cycle.id, + grades_report_subject_id: grades_report_subject_4.id, + assessment_point_id: goal_4_3.id, + weight: 3.0 + }) + std = SchoolsFixtures.student_fixture() # subject 1 @@ -1396,8 +1493,50 @@ defmodule Lanttern.GradesReportsTest do ordinal_value_id: ov_eme.id }) + # subject 4 + + _entry_4_1 = + AssessmentsFixtures.assessment_point_entry_fixture(%{ + student_id: std.id, + assessment_point_id: goal_4_1.id, + scale_id: marking_scale.id, + scale_type: "ordinal", + ordinal_value_id: ov_eme.id + }) + + _entry_4_2 = + AssessmentsFixtures.assessment_point_entry_fixture(%{ + student_id: std.id, + assessment_point_id: goal_4_2.id, + scale_id: marking_scale.id, + scale_type: "ordinal", + ordinal_value_id: ov_eme.id + }) + + _entry_4_3 = + AssessmentsFixtures.assessment_point_entry_fixture(%{ + student_id: std.id, + assessment_point_id: goal_4_3.id, + scale_id: marking_scale.id, + scale_type: "ordinal", + ordinal_value_id: ov_eme.id + }) + # extra cases setup + # UPDATE + EMPTY - pre calculate subject 1, then delete entries + {:ok, %{id: student_grade_report_entry_1_id}, :created} = + GradesReports.calculate_student_grade( + std.id, + grades_report.id, + grades_report_cycle.id, + grades_report_subject_1.id + ) + + Assessments.delete_assessment_point_entry(entry_1_1) + Assessments.delete_assessment_point_entry(entry_1_2) + Assessments.delete_assessment_point_entry(entry_1_3) + # UPDATE CASE - pre calculate subject 3 {:ok, %{id: student_grade_report_entry_3_id}, :created} = GradesReports.calculate_student_grade( @@ -1407,22 +1546,23 @@ defmodule Lanttern.GradesReportsTest do grades_report_subject_3.id ) - # UPDATE + EMPTY - pre calculate subject 1, then delete entries - {:ok, %{id: student_grade_report_entry_1_id}, :created} = + # UPDATE MANUAL - pre calculate subject 4, and change the ordinal_value + {:ok, %{id: student_grade_report_entry_4_id} = sgre_4, :created} = GradesReports.calculate_student_grade( std.id, grades_report.id, grades_report_cycle.id, - grades_report_subject_1.id + grades_report_subject_4.id ) - Assessments.delete_assessment_point_entry(entry_1_1) - Assessments.delete_assessment_point_entry(entry_1_2) - Assessments.delete_assessment_point_entry(entry_1_3) + assert {:ok, _} = + GradesReports.update_student_grade_report_entry(sgre_4, %{ + ordinal_value_id: ov_c.id + }) # assert - assert {:ok, %{created: 1, updated: 1, deleted: 1, noop: 1}} = + assert {:ok, %{created: 1, updated: 1, deleted: 1, noop: 1, updated_with_manual: 1}} = GradesReports.calculate_student_grades( std.id, grades_report.id, @@ -1465,12 +1605,31 @@ defmodule Lanttern.GradesReportsTest do student_grade_report_entry_3_id ) - # sub 4 - should not exist + # sub 4 - same as 3, but with ov = C (manually adjusted) + expected_ordinal_value_id = ov_c.id + expected_composition_ordinal_value_id = ov_e.id + expected_grades_report_cycle_id = grades_report_cycle.id + expected_grades_report_subject_id = grades_report_subject_4.id + + assert %{ + student_id: ^expected_student_id, + composition_normalized_value: 0.4, + composition_ordinal_value_id: ^expected_composition_ordinal_value_id, + ordinal_value_id: ^expected_ordinal_value_id, + grades_report_cycle_id: ^expected_grades_report_cycle_id, + grades_report_subject_id: ^expected_grades_report_subject_id + } = + Repo.get( + StudentGradeReportEntry, + student_grade_report_entry_4_id + ) + + # sub 5 - should not exist assert Repo.get_by( StudentGradeReportEntry, student_id: std.id, grades_report_cycle_id: grades_report_cycle.id, - grades_report_subject_id: grades_report_subject_4.id + grades_report_subject_id: grades_report_subject_5.id ) |> is_nil() end @@ -1493,10 +1652,13 @@ defmodule Lanttern.GradesReportsTest do # std 1: exc - ach - pro = 0.75000 = C (actually irrelevant, will be delete to test update + no entries case) # std 2: eme - ach - exc = 0.85000 = B # std 3: eme - eme - eme = 0.40000 = E + # std 4: eme - eme - eme = 0.40000 = C (view update manual grade below) # - # no entries case: there's a 4th student without entries. it should return nil - # update case: student 3 will be pre calculated. the function should update the std grade report entry - # update + no entries case: when there's no entries but an existing student grades report entry, delete it + # std 1 - update + no entries case: when there's no entries but an existing student grades report entry, delete it + # std 2 - create + # std 3 - update case: student 3 will be pre calculated. the function should update the std grade report entry + # std 4 - update manual grade: when the current grade is different from the composition/calculated one, update but keep manual grade + # no entries case: there's a 5th student without entries. it should return nil marking_scale = GradingFixtures.scale_fixture(%{type: "ordinal"}) @@ -1527,7 +1689,7 @@ defmodule Lanttern.GradesReportsTest do normalized_value: 0.85 }) - _ov_c = + ov_c = GradingFixtures.ordinal_value_fixture(%{scale_id: grading_scale.id, normalized_value: 0.7}) _ov_d = @@ -1604,6 +1766,7 @@ defmodule Lanttern.GradesReportsTest do std_3 = SchoolsFixtures.student_fixture() std_4 = SchoolsFixtures.student_fixture() std_5 = SchoolsFixtures.student_fixture() + std_6 = SchoolsFixtures.student_fixture() # student 1 @@ -1692,11 +1855,40 @@ defmodule Lanttern.GradesReportsTest do ordinal_value_id: ov_eme.id }) - # student 5 (extra) + # student 4 + + _entry_4_1 = + AssessmentsFixtures.assessment_point_entry_fixture(%{ + student_id: std_4.id, + assessment_point_id: goal_1.id, + scale_id: marking_scale.id, + scale_type: "ordinal", + ordinal_value_id: ov_eme.id + }) + + _entry_4_2 = + AssessmentsFixtures.assessment_point_entry_fixture(%{ + student_id: std_4.id, + assessment_point_id: goal_2.id, + scale_id: marking_scale.id, + scale_type: "ordinal", + ordinal_value_id: ov_eme.id + }) + + _entry_4_3 = + AssessmentsFixtures.assessment_point_entry_fixture(%{ + student_id: std_4.id, + assessment_point_id: goal_3.id, + scale_id: marking_scale.id, + scale_type: "ordinal", + ordinal_value_id: ov_eme.id + }) + + # student 6 (extra) - _entry_5_1 = + _entry_6_1 = AssessmentsFixtures.assessment_point_entry_fixture(%{ - student_id: std_5.id, + student_id: std_6.id, assessment_point_id: goal_1.id, scale_id: marking_scale.id, scale_type: "ordinal", @@ -1705,6 +1897,19 @@ defmodule Lanttern.GradesReportsTest do # extra cases setup + # UPDATE + EMPTY - pre calculate student 1, then delete entries + {:ok, %{id: student_1_grade_report_entry_id}, :created} = + GradesReports.calculate_student_grade( + std_1.id, + grades_report.id, + grades_report_cycle.id, + grades_report_subject.id + ) + + Assessments.delete_assessment_point_entry(entry_1_1) + Assessments.delete_assessment_point_entry(entry_1_2) + Assessments.delete_assessment_point_entry(entry_1_3) + # UPDATE CASE - pre calculate student 3 {:ok, %{id: student_3_grade_report_entry_id}, :created} = GradesReports.calculate_student_grade( @@ -1714,24 +1919,25 @@ defmodule Lanttern.GradesReportsTest do grades_report_subject.id ) - # UPDATE + EMPTY - pre calculate student 1, then delete entries - {:ok, %{id: student_1_grade_report_entry_id}, :created} = + # UPDATE MANUAL - pre calculate student 4, and change the ordinal_value + {:ok, %{id: student_4_grade_report_entry_id} = sgre_4, :created} = GradesReports.calculate_student_grade( - std_1.id, + std_4.id, grades_report.id, grades_report_cycle.id, grades_report_subject.id ) - Assessments.delete_assessment_point_entry(entry_1_1) - Assessments.delete_assessment_point_entry(entry_1_2) - Assessments.delete_assessment_point_entry(entry_1_3) + assert {:ok, _} = + GradesReports.update_student_grade_report_entry(sgre_4, %{ + ordinal_value_id: ov_c.id + }) # assert - assert {:ok, %{created: 1, updated: 1, deleted: 1, noop: 1}} = + assert {:ok, %{created: 1, updated: 1, updated_with_manual: 1, deleted: 1, noop: 1}} = GradesReports.calculate_subject_grades( - [std_1.id, std_2.id, std_3.id, std_4.id], + [std_1.id, std_2.id, std_3.id, std_4.id, std_5.id], grades_report.id, grades_report_cycle.id, grades_report_subject.id @@ -1772,10 +1978,30 @@ defmodule Lanttern.GradesReportsTest do student_3_grade_report_entry_id ) - # sub 4 - should not exist + # sub 4 + expected_student_id = std_4.id + expected_ordinal_value_id = ov_c.id + expected_composition_ordinal_value_id = ov_e.id + expected_grades_report_cycle_id = grades_report_cycle.id + expected_grades_report_subject_id = grades_report_subject.id + + assert %{ + composition_normalized_value: 0.4, + student_id: ^expected_student_id, + ordinal_value_id: ^expected_ordinal_value_id, + composition_ordinal_value_id: ^expected_composition_ordinal_value_id, + grades_report_cycle_id: ^expected_grades_report_cycle_id, + grades_report_subject_id: ^expected_grades_report_subject_id + } = + Repo.get( + StudentGradeReportEntry, + student_4_grade_report_entry_id + ) + + # sub 5 - should not exist assert Repo.get_by( StudentGradeReportEntry, - student_id: std_4.id, + student_id: std_5.id, grades_report_cycle_id: grades_report_cycle.id, grades_report_subject_id: grades_report_subject.id ) @@ -1800,10 +2026,13 @@ defmodule Lanttern.GradesReportsTest do # std 1 sub 1: exc - ach - pro = 0.75000 = C (actually irrelevant, will be delete to test update + no entries case) # std 2 sub 2: eme - ach - exc = 0.85000 = B # std 3 sub 3: eme - eme - eme = 0.40000 = E + # std 4 sub 3: eme - eme - eme = 0.40000 = C (view update manual grade below) # - # no entries case: there's a 4th student without entries. it should return nil - # update case: student 3 will be pre calculated. the function should update the std grade report entry - # update + no entries case: when there's no entries but an existing student grades report entry, delete it + # 1 update + no entries case: when there's no entries but an existing student grades report entry, delete it + # 2 create + # 3 update case: subject 3 will be pre calculated. the function should update the std grade report entry + # 4 update manual grade: when the current grade is different from the composition/calculated one, update but keep manual grade + # 5 no entries case: there's a 5th subject without entries. it should return nil marking_scale = GradingFixtures.scale_fixture(%{type: "ordinal"}) @@ -1834,7 +2063,7 @@ defmodule Lanttern.GradesReportsTest do normalized_value: 0.85 }) - _ov_c = + ov_c = GradingFixtures.ordinal_value_fixture(%{scale_id: grading_scale.id, normalized_value: 0.7}) _ov_d = @@ -2017,6 +2246,7 @@ defmodule Lanttern.GradesReportsTest do std_3 = SchoolsFixtures.student_fixture() std_4 = SchoolsFixtures.student_fixture() std_5 = SchoolsFixtures.student_fixture() + std_6 = SchoolsFixtures.student_fixture() # student 1 @@ -2105,11 +2335,40 @@ defmodule Lanttern.GradesReportsTest do ordinal_value_id: ov_eme.id }) - # student 5 (extra) + # student 4 - _entry_5_1 = + _entry_4_1 = AssessmentsFixtures.assessment_point_entry_fixture(%{ - student_id: std_5.id, + student_id: std_4.id, + assessment_point_id: goal_3_1.id, + scale_id: marking_scale.id, + scale_type: "ordinal", + ordinal_value_id: ov_eme.id + }) + + _entry_4_2 = + AssessmentsFixtures.assessment_point_entry_fixture(%{ + student_id: std_4.id, + assessment_point_id: goal_3_2.id, + scale_id: marking_scale.id, + scale_type: "ordinal", + ordinal_value_id: ov_eme.id + }) + + _entry_4_3 = + AssessmentsFixtures.assessment_point_entry_fixture(%{ + student_id: std_4.id, + assessment_point_id: goal_3_3.id, + scale_id: marking_scale.id, + scale_type: "ordinal", + ordinal_value_id: ov_eme.id + }) + + # student 6 (extra) + + _entry_6_1 = + AssessmentsFixtures.assessment_point_entry_fixture(%{ + student_id: std_6.id, assessment_point_id: goal_1_1.id, scale_id: marking_scale.id, scale_type: "ordinal", @@ -2118,6 +2377,19 @@ defmodule Lanttern.GradesReportsTest do # extra cases setup + # UPDATE + EMPTY - pre calculate student 1, then delete entries + {:ok, %{id: student_1_grade_report_entry_id}, :created} = + GradesReports.calculate_student_grade( + std_1.id, + grades_report.id, + grades_report_cycle.id, + grades_report_subject_1.id + ) + + Assessments.delete_assessment_point_entry(entry_1_1) + Assessments.delete_assessment_point_entry(entry_1_2) + Assessments.delete_assessment_point_entry(entry_1_3) + # UPDATE CASE - pre calculate student 3 {:ok, %{id: student_3_grade_report_entry_id}, :created} = GradesReports.calculate_student_grade( @@ -2127,24 +2399,25 @@ defmodule Lanttern.GradesReportsTest do grades_report_subject_3.id ) - # UPDATE + EMPTY - pre calculate student 1, then delete entries - {:ok, %{id: student_1_grade_report_entry_id}, :created} = + # UPDATE MANUAL - pre calculate student 4, and change the ordinal_value + {:ok, %{id: student_4_grade_report_entry_id} = sgre_4, :created} = GradesReports.calculate_student_grade( - std_1.id, + std_4.id, grades_report.id, grades_report_cycle.id, - grades_report_subject_1.id + grades_report_subject_3.id ) - Assessments.delete_assessment_point_entry(entry_1_1) - Assessments.delete_assessment_point_entry(entry_1_2) - Assessments.delete_assessment_point_entry(entry_1_3) + assert {:ok, _} = + GradesReports.update_student_grade_report_entry(sgre_4, %{ + ordinal_value_id: ov_c.id + }) # assert - assert {:ok, %{created: 1, updated: 1, deleted: 1, noop: 9}} = + assert {:ok, %{created: 1, updated: 1, updated_with_manual: 1, deleted: 1, noop: 11}} = GradesReports.calculate_cycle_grades( - [std_1.id, std_2.id, std_3.id, std_4.id], + [std_1.id, std_2.id, std_3.id, std_4.id, std_5.id], grades_report.id, grades_report_cycle.id ) @@ -2152,7 +2425,7 @@ defmodule Lanttern.GradesReportsTest do # std 1 - previously calculated should not exist anymore assert Repo.get(StudentGradeReportEntry, student_1_grade_report_entry_id) |> is_nil() - # sub 2 + # std 2 expected_ordinal_value_id = ov_b.id assert %{ @@ -2166,7 +2439,7 @@ defmodule Lanttern.GradesReportsTest do grades_report_subject_id: grades_report_subject_2.id ) - # sub 3 + # std 3 expected_student_id = std_3.id expected_ordinal_value_id = ov_e.id expected_grades_report_cycle_id = grades_report_cycle.id @@ -2184,10 +2457,30 @@ defmodule Lanttern.GradesReportsTest do student_3_grade_report_entry_id ) - # sub 4 - should not exist + # std 4 + expected_student_id = std_4.id + expected_ordinal_value_id = ov_c.id + expected_composition_ordinal_value_id = ov_e.id + expected_grades_report_cycle_id = grades_report_cycle.id + expected_grades_report_subject_id = grades_report_subject_3.id + + assert %{ + composition_normalized_value: 0.4, + student_id: ^expected_student_id, + ordinal_value_id: ^expected_ordinal_value_id, + composition_ordinal_value_id: ^expected_composition_ordinal_value_id, + grades_report_cycle_id: ^expected_grades_report_cycle_id, + grades_report_subject_id: ^expected_grades_report_subject_id + } = + Repo.get( + StudentGradeReportEntry, + student_4_grade_report_entry_id + ) + + # std 5 - should not exist assert Repo.get_by( StudentGradeReportEntry, - student_id: std_4.id, + student_id: std_5.id, grades_report_cycle_id: grades_report_cycle.id ) |> is_nil() From 9cdb0dc693f2cd9a01a9dc084d6023f29fb22837 Mon Sep 17 00:00:00 2001 From: endoooo Date: Wed, 19 Jun 2024 15:23:35 -0300 Subject: [PATCH 3/5] feat: added warning when calculating cell with manual grade in `<.students_grades_grid>` --- .../components/grades_reports_components.ex | 25 +++++++++++++++++++ .../id/students_grades_component.ex | 3 ++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/lib/lanttern_web/components/grades_reports_components.ex b/lib/lanttern_web/components/grades_reports_components.ex index 1a491148..19316f0e 100644 --- a/lib/lanttern_web/components/grades_reports_components.ex +++ b/lib/lanttern_web/components/grades_reports_components.ex @@ -454,9 +454,27 @@ defmodule LantternWeb.GradesReportsComponents do else: "border-ltrn-teacher-accent bg-ltrn-teacher-lightest" end + has_manual_grade = + case assigns.student_grade_report_entry do + %{ + ordinal_value_id: ov_id, + composition_ordinal_value_id: comp_ov_id + } + when ov_id != comp_ov_id -> + true + + %{score: score, composition_score: comp_score} + when score != comp_score -> + true + + _ -> + false + end + assigns = assigns |> assign(:bg_class, bg_class) + |> assign(:has_manual_grade, has_manual_grade) ~H"""
diff --git a/lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex b/lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex index 493b68d5..08c2bb91 100644 --- a/lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex +++ b/lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex @@ -365,7 +365,8 @@ defmodule LantternWeb.ReportCardLive.StudentsGradesComponent do student_id, socket.assigns.grades_report.id, socket.assigns.current_grades_report_cycle.id, - grades_report_subject_id + grades_report_subject_id, + force_overwrite: true ) |> case do {:ok, nil, _} -> From c4146997033eb0406a583b1cf409b074f027f51e Mon Sep 17 00:00:00 2001 From: endoooo Date: Thu, 20 Jun 2024 08:41:49 -0300 Subject: [PATCH 4/5] chore: updated translation and versions --- .../id/students_grades_component.ex | 4 +- mix.exs | 2 +- priv/gettext/default.pot | 68 +++++++++++-------- priv/gettext/en/LC_MESSAGES/default.po | 68 +++++++++++-------- priv/gettext/pt_BR/LC_MESSAGES/default.po | 68 +++++++++++-------- 5 files changed, 123 insertions(+), 87 deletions(-) diff --git a/lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex b/lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex index 08c2bb91..69ecbc58 100644 --- a/lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex +++ b/lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex @@ -431,8 +431,8 @@ defmodule LantternWeb.ReportCardLive.StudentsGradesComponent do defp build_calculation_results_message([{:updated_with_manual, count} | results], msgs) do msg = ngettext( - "1 grade composition updated (manual grade not changed)", - "%{count} grades compositions updated (manual grades not changed)", + "1 grade partially updated (only composition, manual grade not changed)", + "%{count} grades partially updated (only compositions, manual grades not changed)", count ) diff --git a/mix.exs b/mix.exs index 714705ee..f81d1b04 100644 --- a/mix.exs +++ b/mix.exs @@ -4,7 +4,7 @@ defmodule Lanttern.MixProject do def project do [ app: :lanttern, - version: "2024.6.14-alpha.24", + version: "2024.6.20-alpha.25", elixir: "~> 1.15", elixirc_paths: elixirc_paths(Mix.env()), start_permanent: Mix.env() == :prod, diff --git a/priv/gettext/default.pot b/priv/gettext/default.pot index 7b51e24f..6fb8ad89 100644 --- a/priv/gettext/default.pot +++ b/priv/gettext/default.pot @@ -22,7 +22,7 @@ msgstr "" msgid "Assessment points" msgstr "" -#: lib/lanttern_web/components/grades_reports_components.ex:578 +#: lib/lanttern_web/components/grades_reports_components.ex:603 #: lib/lanttern_web/live/pages/curriculum/curricula_live.ex:11 #: lib/lanttern_web/live/pages/strands/moment/id/overview_component.ex:12 #: lib/lanttern_web/live/shared/assessments/assessment_point_form_component.ex:48 @@ -373,7 +373,7 @@ msgstr "" msgid "About" msgstr "" -#: lib/lanttern_web/components/grades_reports_components.ex:579 +#: lib/lanttern_web/components/grades_reports_components.ex:604 #: lib/lanttern_web/live/pages/strands/id/strand_live.html.heex:37 #: lib/lanttern_web/live/pages/strands/moment/id/moment_live.html.heex:46 #, elixir-autogen, elixir-format @@ -655,7 +655,7 @@ msgstr "" msgid "Select strand" msgstr "" -#: lib/lanttern_web/components/grades_reports_components.ex:577 +#: lib/lanttern_web/components/grades_reports_components.ex:602 #: lib/lanttern_web/live/shared/learning_context/moment_form_component.ex:25 #, elixir-autogen, elixir-format msgid "Strand" @@ -872,7 +872,7 @@ msgstr "" #: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:283 #: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:314 #: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:350 -#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:382 +#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:383 #, elixir-autogen, elixir-format msgid "Something went wrong" msgstr "" @@ -907,28 +907,28 @@ msgstr "" msgid "You may already have some entries for this assessment point. Changing the scale when entries exist is not allowed, as it would cause data loss." msgstr "" -#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:437 +#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:449 #, elixir-autogen, elixir-format msgid "1 grade calculation skipped (no assessment point entries)" msgid_plural "%{count} grades skipped (no assessment point entries)" msgstr[0] "" msgstr[1] "" -#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:421 +#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:422 #, elixir-autogen, elixir-format msgid "1 grade created" msgid_plural "%{count} grades created" msgstr[0] "" msgstr[1] "" -#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:431 +#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:443 #, elixir-autogen, elixir-format msgid "1 grade removed" msgid_plural "%{count} grades removed" msgstr[0] "" msgstr[1] "" -#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:426 +#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:427 #, elixir-autogen, elixir-format msgid "1 grade updated" msgid_plural "%{count} grades updated" @@ -997,7 +997,7 @@ msgstr "" msgid "Calculate all" msgstr "" -#: lib/lanttern_web/components/grades_reports_components.ex:503 +#: lib/lanttern_web/components/grades_reports_components.ex:528 #, elixir-autogen, elixir-format msgid "Calculate grade" msgstr "" @@ -1028,7 +1028,7 @@ msgstr "" msgid "Code" msgstr "" -#: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:134 +#: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:136 #: lib/lanttern_web/live/shared/grades_reports/student_grade_report_entry_form_component.ex:49 #, elixir-autogen, elixir-format msgid "Comment" @@ -1094,12 +1094,12 @@ msgstr "" msgid "Curriculum items" msgstr "" -#: lib/lanttern_web/components/reporting_components.ex:67 +#: lib/lanttern_web/components/reporting_components.ex:68 #: lib/lanttern_web/live/pages/grading/grades_reports_live.html.heex:39 #: lib/lanttern_web/live/pages/report_cards/id/report_card_live.html.heex:14 #: lib/lanttern_web/live/pages/student_report_card/id/strand_report/strand_report_id/student_strand_report_live.html.heex:34 #: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:23 -#: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:105 +#: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:107 #: lib/lanttern_web/live/shared/reporting/report_card_form_component.ex:37 #, elixir-autogen, elixir-format msgid "Cycle" @@ -1211,7 +1211,7 @@ msgstr "" msgid "Error deleting strand report" msgstr "" -#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:403 +#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:404 #, elixir-autogen, elixir-format msgid "Error deleting student grade report entry" msgstr "" @@ -1247,7 +1247,7 @@ msgstr "" msgid "Filter curriculum items by year" msgstr "" -#: lib/lanttern_web/components/grades_reports_components.ex:611 +#: lib/lanttern_web/components/grades_reports_components.ex:636 #, elixir-autogen, elixir-format msgid "Final grade" msgstr "" @@ -1257,18 +1257,18 @@ msgstr "" msgid "Final strand goals assessment for" msgstr "" -#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:378 +#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:379 #, elixir-autogen, elixir-format msgid "Grade calculated succesfully" msgstr "" #: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:113 -#: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:137 +#: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:139 #, elixir-autogen, elixir-format msgid "Grade composition" msgstr "" -#: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:80 +#: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:82 #, elixir-autogen, elixir-format msgid "Grade details" msgstr "" @@ -1279,7 +1279,7 @@ msgid "Grade report deleted" msgstr "" #: lib/lanttern_web/live/pages/report_cards/id/report_card_live.html.heex:40 -#: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:61 +#: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:63 #, elixir-autogen, elixir-format msgid "Grades" msgstr "" @@ -1416,7 +1416,7 @@ msgstr "" msgid "No assesment points in this grade composition" msgstr "" -#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:373 +#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:374 #, elixir-autogen, elixir-format msgid "No assessment point entries for this grade composition" msgstr "" @@ -1482,7 +1482,7 @@ msgstr "" msgid "No subjects linked to this grades report" msgstr "" -#: lib/lanttern_web/components/grades_reports_components.ex:581 +#: lib/lanttern_web/components/grades_reports_components.ex:606 #, elixir-autogen, elixir-format msgid "Normalized value" msgstr "" @@ -1504,7 +1504,7 @@ msgstr "" msgid "Preview" msgstr "" -#: lib/lanttern_web/components/grades_reports_components.ex:485 +#: lib/lanttern_web/components/grades_reports_components.ex:503 #, elixir-autogen, elixir-format msgid "Recalculate grade" msgstr "" @@ -1669,7 +1669,7 @@ msgstr "" msgid "Student grade report entry created successfully" msgstr "" -#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:395 +#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:396 #, elixir-autogen, elixir-format msgid "Student grade report entry deleted" msgstr "" @@ -1710,7 +1710,7 @@ msgstr "" msgid "Sub cycle" msgstr "" -#: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:97 +#: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:99 #, elixir-autogen, elixir-format msgid "Subject" msgstr "" @@ -1750,7 +1750,7 @@ msgstr "" msgid "Viewing all grades reports" msgstr "" -#: lib/lanttern_web/components/grades_reports_components.ex:580 +#: lib/lanttern_web/components/grades_reports_components.ex:605 #: lib/lanttern_web/live/shared/grading/grade_composition_overlay_component.ex:36 #, elixir-autogen, elixir-format msgid "Weight" @@ -2282,7 +2282,7 @@ msgstr "" msgid "Students report cards access updated" msgstr "" -#: lib/lanttern_web/components/reporting_components.ex:79 +#: lib/lanttern_web/components/reporting_components.ex:80 #, elixir-autogen, elixir-format msgid "Under development" msgstr "" @@ -2541,8 +2541,8 @@ msgstr "" msgid "Simplified" msgstr "" -#: lib/lanttern_web/components/reporting_components.ex:151 -#: lib/lanttern_web/components/reporting_components.ex:168 +#: lib/lanttern_web/components/reporting_components.ex:152 +#: lib/lanttern_web/components/reporting_components.ex:169 #, elixir-autogen, elixir-format msgid "Student self-assessment" msgstr "" @@ -2587,7 +2587,7 @@ msgstr "" msgid "Are you sure? Grades related to this subject will be created, updated, and removed based on their grade composition." msgstr "" -#: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:131 +#: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:133 #, elixir-autogen, elixir-format msgid "Grade before retake process" msgstr "" @@ -2616,3 +2616,15 @@ msgstr "" #, elixir-autogen, elixir-format msgid "Save self-assessments" msgstr "" + +#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:433 +#, elixir-autogen, elixir-format +msgid "1 grade partially updated (only composition, manual grade not changed)" +msgid_plural "%{count} grades partially updated (only compositions, manual grades not changed)" +msgstr[0] "" +msgstr[1] "" + +#: lib/lanttern_web/components/grades_reports_components.ex:508 +#, elixir-autogen, elixir-format +msgid "There is a manual grade change that will be overwritten by this operation. Are you sure you want to proceed?" +msgstr "" diff --git a/priv/gettext/en/LC_MESSAGES/default.po b/priv/gettext/en/LC_MESSAGES/default.po index aa19f440..4e71b7c2 100644 --- a/priv/gettext/en/LC_MESSAGES/default.po +++ b/priv/gettext/en/LC_MESSAGES/default.po @@ -22,7 +22,7 @@ msgstr "" msgid "Assessment points" msgstr "" -#: lib/lanttern_web/components/grades_reports_components.ex:578 +#: lib/lanttern_web/components/grades_reports_components.ex:603 #: lib/lanttern_web/live/pages/curriculum/curricula_live.ex:11 #: lib/lanttern_web/live/pages/strands/moment/id/overview_component.ex:12 #: lib/lanttern_web/live/shared/assessments/assessment_point_form_component.ex:48 @@ -373,7 +373,7 @@ msgstr "" msgid "About" msgstr "" -#: lib/lanttern_web/components/grades_reports_components.ex:579 +#: lib/lanttern_web/components/grades_reports_components.ex:604 #: lib/lanttern_web/live/pages/strands/id/strand_live.html.heex:37 #: lib/lanttern_web/live/pages/strands/moment/id/moment_live.html.heex:46 #, elixir-autogen, elixir-format, fuzzy @@ -655,7 +655,7 @@ msgstr "" msgid "Select strand" msgstr "" -#: lib/lanttern_web/components/grades_reports_components.ex:577 +#: lib/lanttern_web/components/grades_reports_components.ex:602 #: lib/lanttern_web/live/shared/learning_context/moment_form_component.ex:25 #, elixir-autogen, elixir-format, fuzzy msgid "Strand" @@ -872,7 +872,7 @@ msgstr "" #: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:283 #: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:314 #: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:350 -#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:382 +#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:383 #, elixir-autogen, elixir-format, fuzzy msgid "Something went wrong" msgstr "" @@ -907,28 +907,28 @@ msgstr "" msgid "You may already have some entries for this assessment point. Changing the scale when entries exist is not allowed, as it would cause data loss." msgstr "" -#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:437 +#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:449 #, elixir-autogen, elixir-format msgid "1 grade calculation skipped (no assessment point entries)" msgid_plural "%{count} grades skipped (no assessment point entries)" msgstr[0] "" msgstr[1] "" -#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:421 +#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:422 #, elixir-autogen, elixir-format msgid "1 grade created" msgid_plural "%{count} grades created" msgstr[0] "" msgstr[1] "" -#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:431 +#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:443 #, elixir-autogen, elixir-format msgid "1 grade removed" msgid_plural "%{count} grades removed" msgstr[0] "" msgstr[1] "" -#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:426 +#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:427 #, elixir-autogen, elixir-format msgid "1 grade updated" msgid_plural "%{count} grades updated" @@ -997,7 +997,7 @@ msgstr "" msgid "Calculate all" msgstr "" -#: lib/lanttern_web/components/grades_reports_components.ex:503 +#: lib/lanttern_web/components/grades_reports_components.ex:528 #, elixir-autogen, elixir-format msgid "Calculate grade" msgstr "" @@ -1028,7 +1028,7 @@ msgstr "" msgid "Code" msgstr "" -#: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:134 +#: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:136 #: lib/lanttern_web/live/shared/grades_reports/student_grade_report_entry_form_component.ex:49 #, elixir-autogen, elixir-format, fuzzy msgid "Comment" @@ -1094,12 +1094,12 @@ msgstr "" msgid "Curriculum items" msgstr "" -#: lib/lanttern_web/components/reporting_components.ex:67 +#: lib/lanttern_web/components/reporting_components.ex:68 #: lib/lanttern_web/live/pages/grading/grades_reports_live.html.heex:39 #: lib/lanttern_web/live/pages/report_cards/id/report_card_live.html.heex:14 #: lib/lanttern_web/live/pages/student_report_card/id/strand_report/strand_report_id/student_strand_report_live.html.heex:34 #: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:23 -#: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:105 +#: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:107 #: lib/lanttern_web/live/shared/reporting/report_card_form_component.ex:37 #, elixir-autogen, elixir-format msgid "Cycle" @@ -1211,7 +1211,7 @@ msgstr "" msgid "Error deleting strand report" msgstr "" -#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:403 +#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:404 #, elixir-autogen, elixir-format msgid "Error deleting student grade report entry" msgstr "" @@ -1247,7 +1247,7 @@ msgstr "" msgid "Filter curriculum items by year" msgstr "" -#: lib/lanttern_web/components/grades_reports_components.ex:611 +#: lib/lanttern_web/components/grades_reports_components.ex:636 #, elixir-autogen, elixir-format msgid "Final grade" msgstr "" @@ -1257,18 +1257,18 @@ msgstr "" msgid "Final strand goals assessment for" msgstr "" -#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:378 +#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:379 #, elixir-autogen, elixir-format msgid "Grade calculated succesfully" msgstr "" #: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:113 -#: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:137 +#: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:139 #, elixir-autogen, elixir-format msgid "Grade composition" msgstr "" -#: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:80 +#: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:82 #, elixir-autogen, elixir-format msgid "Grade details" msgstr "" @@ -1279,7 +1279,7 @@ msgid "Grade report deleted" msgstr "" #: lib/lanttern_web/live/pages/report_cards/id/report_card_live.html.heex:40 -#: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:61 +#: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:63 #, elixir-autogen, elixir-format msgid "Grades" msgstr "" @@ -1416,7 +1416,7 @@ msgstr "" msgid "No assesment points in this grade composition" msgstr "" -#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:373 +#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:374 #, elixir-autogen, elixir-format, fuzzy msgid "No assessment point entries for this grade composition" msgstr "" @@ -1482,7 +1482,7 @@ msgstr "" msgid "No subjects linked to this grades report" msgstr "" -#: lib/lanttern_web/components/grades_reports_components.ex:581 +#: lib/lanttern_web/components/grades_reports_components.ex:606 #, elixir-autogen, elixir-format msgid "Normalized value" msgstr "" @@ -1504,7 +1504,7 @@ msgstr "" msgid "Preview" msgstr "" -#: lib/lanttern_web/components/grades_reports_components.ex:485 +#: lib/lanttern_web/components/grades_reports_components.ex:503 #, elixir-autogen, elixir-format msgid "Recalculate grade" msgstr "" @@ -1669,7 +1669,7 @@ msgstr "" msgid "Student grade report entry created successfully" msgstr "" -#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:395 +#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:396 #, elixir-autogen, elixir-format msgid "Student grade report entry deleted" msgstr "" @@ -1710,7 +1710,7 @@ msgstr "" msgid "Sub cycle" msgstr "" -#: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:97 +#: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:99 #, elixir-autogen, elixir-format, fuzzy msgid "Subject" msgstr "" @@ -1750,7 +1750,7 @@ msgstr "" msgid "Viewing all grades reports" msgstr "" -#: lib/lanttern_web/components/grades_reports_components.ex:580 +#: lib/lanttern_web/components/grades_reports_components.ex:605 #: lib/lanttern_web/live/shared/grading/grade_composition_overlay_component.ex:36 #, elixir-autogen, elixir-format msgid "Weight" @@ -2282,7 +2282,7 @@ msgstr "" msgid "Students report cards access updated" msgstr "" -#: lib/lanttern_web/components/reporting_components.ex:79 +#: lib/lanttern_web/components/reporting_components.ex:80 #, elixir-autogen, elixir-format msgid "Under development" msgstr "" @@ -2541,8 +2541,8 @@ msgstr "" msgid "Simplified" msgstr "" -#: lib/lanttern_web/components/reporting_components.ex:151 -#: lib/lanttern_web/components/reporting_components.ex:168 +#: lib/lanttern_web/components/reporting_components.ex:152 +#: lib/lanttern_web/components/reporting_components.ex:169 #, elixir-autogen, elixir-format msgid "Student self-assessment" msgstr "" @@ -2587,7 +2587,7 @@ msgstr "" msgid "Are you sure? Grades related to this subject will be created, updated, and removed based on their grade composition." msgstr "" -#: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:131 +#: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:133 #, elixir-autogen, elixir-format msgid "Grade before retake process" msgstr "" @@ -2616,3 +2616,15 @@ msgstr "" #, elixir-autogen, elixir-format, fuzzy msgid "Save self-assessments" msgstr "" + +#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:433 +#, elixir-autogen, elixir-format +msgid "1 grade partially updated (only composition, manual grade not changed)" +msgid_plural "%{count} grades partially updated (only compositions, manual grades not changed)" +msgstr[0] "" +msgstr[1] "" + +#: lib/lanttern_web/components/grades_reports_components.ex:508 +#, elixir-autogen, elixir-format +msgid "There is a manual grade change that will be overwritten by this operation. Are you sure you want to proceed?" +msgstr "" diff --git a/priv/gettext/pt_BR/LC_MESSAGES/default.po b/priv/gettext/pt_BR/LC_MESSAGES/default.po index e83ceaf2..f6928671 100644 --- a/priv/gettext/pt_BR/LC_MESSAGES/default.po +++ b/priv/gettext/pt_BR/LC_MESSAGES/default.po @@ -22,7 +22,7 @@ msgstr "Ações" msgid "Assessment points" msgstr "Pontos de avaliação" -#: lib/lanttern_web/components/grades_reports_components.ex:578 +#: lib/lanttern_web/components/grades_reports_components.ex:603 #: lib/lanttern_web/live/pages/curriculum/curricula_live.ex:11 #: lib/lanttern_web/live/pages/strands/moment/id/overview_component.ex:12 #: lib/lanttern_web/live/shared/assessments/assessment_point_form_component.ex:48 @@ -373,7 +373,7 @@ msgstr "anos" msgid "About" msgstr "Sobre" -#: lib/lanttern_web/components/grades_reports_components.ex:579 +#: lib/lanttern_web/components/grades_reports_components.ex:604 #: lib/lanttern_web/live/pages/strands/id/strand_live.html.heex:37 #: lib/lanttern_web/live/pages/strands/moment/id/moment_live.html.heex:46 #, elixir-autogen, elixir-format @@ -655,7 +655,7 @@ msgstr "Selecionar item curricular" msgid "Select strand" msgstr "Selecionar trilha" -#: lib/lanttern_web/components/grades_reports_components.ex:577 +#: lib/lanttern_web/components/grades_reports_components.ex:602 #: lib/lanttern_web/live/shared/learning_context/moment_form_component.ex:25 #, elixir-autogen, elixir-format msgid "Strand" @@ -872,7 +872,7 @@ msgstr "Salvar momento" #: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:283 #: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:314 #: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:350 -#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:382 +#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:383 #, elixir-autogen, elixir-format msgid "Something went wrong" msgstr "Algo deu errado" @@ -907,28 +907,28 @@ msgstr "Você ainda não poussui anotações para este momento" msgid "You may already have some entries for this assessment point. Changing the scale when entries exist is not allowed, as it would cause data loss." msgstr "Você já deve possuir registros para este ponto de avaliação. Alterar a escala quando registros já existem não é permitido, pois acarretaria perda de dados." -#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:437 +#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:449 #, elixir-autogen, elixir-format msgid "1 grade calculation skipped (no assessment point entries)" msgid_plural "%{count} grades skipped (no assessment point entries)" msgstr[0] "1 cálculo de nota ignorado (sem registros de ponto de avaliação)" msgstr[1] "%{count} cálculos de nota ignorados (sem registros de ponto de avaliação)" -#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:421 +#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:422 #, elixir-autogen, elixir-format msgid "1 grade created" msgid_plural "%{count} grades created" msgstr[0] "1 nota criada" msgstr[1] "%{count} notas criadas" -#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:431 +#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:443 #, elixir-autogen, elixir-format msgid "1 grade removed" msgid_plural "%{count} grades removed" msgstr[0] "1 nota removida" msgstr[1] "%{count} notas removidas" -#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:426 +#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:427 #, elixir-autogen, elixir-format msgid "1 grade updated" msgid_plural "%{count} grades updated" @@ -997,7 +997,7 @@ msgstr "Cor de fundo inválida. Utilize cores hex." msgid "Calculate all" msgstr "Calcular tudo" -#: lib/lanttern_web/components/grades_reports_components.ex:503 +#: lib/lanttern_web/components/grades_reports_components.ex:528 #, elixir-autogen, elixir-format msgid "Calculate grade" msgstr "Calcular nota" @@ -1028,7 +1028,7 @@ msgstr "Cards" msgid "Code" msgstr "Código" -#: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:134 +#: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:136 #: lib/lanttern_web/live/shared/grades_reports/student_grade_report_entry_form_component.ex:49 #, elixir-autogen, elixir-format msgid "Comment" @@ -1094,12 +1094,12 @@ msgstr "Item curricular removido" msgid "Curriculum items" msgstr "Itens curriculares" -#: lib/lanttern_web/components/reporting_components.ex:67 +#: lib/lanttern_web/components/reporting_components.ex:68 #: lib/lanttern_web/live/pages/grading/grades_reports_live.html.heex:39 #: lib/lanttern_web/live/pages/report_cards/id/report_card_live.html.heex:14 #: lib/lanttern_web/live/pages/student_report_card/id/strand_report/strand_report_id/student_strand_report_live.html.heex:34 #: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:23 -#: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:105 +#: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:107 #: lib/lanttern_web/live/shared/reporting/report_card_form_component.ex:37 #, elixir-autogen, elixir-format msgid "Cycle" @@ -1211,7 +1211,7 @@ msgstr "Erro ao deletar report card" msgid "Error deleting strand report" msgstr "Erro ao deletar relatório da trilha" -#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:403 +#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:404 #, elixir-autogen, elixir-format msgid "Error deleting student grade report entry" msgstr "Erro ao deletar registro de relatório de nota de estudante" @@ -1247,7 +1247,7 @@ msgstr "Filtrar itens curriculares por disciplina" msgid "Filter curriculum items by year" msgstr "Filtrar itens curriculares por ano" -#: lib/lanttern_web/components/grades_reports_components.ex:611 +#: lib/lanttern_web/components/grades_reports_components.ex:636 #, elixir-autogen, elixir-format msgid "Final grade" msgstr "Nota final" @@ -1257,18 +1257,18 @@ msgstr "Nota final" msgid "Final strand goals assessment for" msgstr "Avaliação final do objetivo da trilha" -#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:378 +#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:379 #, elixir-autogen, elixir-format msgid "Grade calculated succesfully" msgstr "Nota calculada com sucesso" #: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:113 -#: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:137 +#: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:139 #, elixir-autogen, elixir-format msgid "Grade composition" msgstr "Composição de nota" -#: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:80 +#: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:82 #, elixir-autogen, elixir-format msgid "Grade details" msgstr "Detalhes da nota" @@ -1279,7 +1279,7 @@ msgid "Grade report deleted" msgstr "Relatório de nota deletada" #: lib/lanttern_web/live/pages/report_cards/id/report_card_live.html.heex:40 -#: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:61 +#: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:63 #, elixir-autogen, elixir-format msgid "Grades" msgstr "Notas" @@ -1416,7 +1416,7 @@ msgstr "Novo report card" msgid "No assesment points in this grade composition" msgstr "Nenhum ponto de avaliação para esta composição de nota" -#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:373 +#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:374 #, elixir-autogen, elixir-format msgid "No assessment point entries for this grade composition" msgstr "Nenhum ponto de avaliação para esta composição de nota" @@ -1482,7 +1482,7 @@ msgstr "Nenhuma disciplina vinculada" msgid "No subjects linked to this grades report" msgstr "Nenhuma disciplina vinculada a este relatório de notas" -#: lib/lanttern_web/components/grades_reports_components.ex:581 +#: lib/lanttern_web/components/grades_reports_components.ex:606 #, elixir-autogen, elixir-format msgid "Normalized value" msgstr "Valor normalizado" @@ -1504,7 +1504,7 @@ msgstr "Resultados parciais" msgid "Preview" msgstr "Prévia" -#: lib/lanttern_web/components/grades_reports_components.ex:485 +#: lib/lanttern_web/components/grades_reports_components.ex:503 #, elixir-autogen, elixir-format msgid "Recalculate grade" msgstr "Recalcular nota" @@ -1669,7 +1669,7 @@ msgstr "Estudante já vinculado ao report card" msgid "Student grade report entry created successfully" msgstr "Registro de relatório de nota de estudante criado com sucesso" -#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:395 +#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:396 #, elixir-autogen, elixir-format msgid "Student grade report entry deleted" msgstr "Registro de relatório de nota de estudante deletado" @@ -1710,7 +1710,7 @@ msgstr "Filtro de notas de estudantes" msgid "Sub cycle" msgstr "Sub ciclo" -#: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:97 +#: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:99 #, elixir-autogen, elixir-format msgid "Subject" msgstr "Disciplina" @@ -1750,7 +1750,7 @@ msgstr "Utilize esta funcionalidade para adicionar uma camada de organização a msgid "Viewing all grades reports" msgstr "Visualizando todos os relatórios de nota" -#: lib/lanttern_web/components/grades_reports_components.ex:580 +#: lib/lanttern_web/components/grades_reports_components.ex:605 #: lib/lanttern_web/live/shared/grading/grade_composition_overlay_component.ex:36 #, elixir-autogen, elixir-format msgid "Weight" @@ -2282,7 +2282,7 @@ msgstr "Acesso de estudantes" msgid "Students report cards access updated" msgstr "Report cards de estudante atualizados" -#: lib/lanttern_web/components/reporting_components.ex:79 +#: lib/lanttern_web/components/reporting_components.ex:80 #, elixir-autogen, elixir-format msgid "Under development" msgstr "Em desenvolvimento" @@ -2541,8 +2541,8 @@ msgstr "Nível de informação" msgid "Simplified" msgstr "Simplificado" -#: lib/lanttern_web/components/reporting_components.ex:151 -#: lib/lanttern_web/components/reporting_components.ex:168 +#: lib/lanttern_web/components/reporting_components.ex:152 +#: lib/lanttern_web/components/reporting_components.ex:169 #, elixir-autogen, elixir-format msgid "Student self-assessment" msgstr "Autoavaliação do estudante" @@ -2587,7 +2587,7 @@ msgstr "Você tem certeza? Notas relacionadas ao estudante serão criadas, atual msgid "Are you sure? Grades related to this subject will be created, updated, and removed based on their grade composition." msgstr "Você tem certeza? Notas relacionadas à disciplina serão criadas, atualizadas e removidas com base em suas composições." -#: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:131 +#: lib/lanttern_web/live/pages/student_report_card/id/student_report_card_live.html.heex:133 #, elixir-autogen, elixir-format msgid "Grade before retake process" msgstr "Nota anterior ao processo de recuperação" @@ -2616,3 +2616,15 @@ msgstr "Você está registrando autoavaliações de estudantes" #, elixir-autogen, elixir-format msgid "Save self-assessments" msgstr "Salvar autoavaliações" + +#: lib/lanttern_web/live/pages/report_cards/id/students_grades_component.ex:433 +#, elixir-autogen, elixir-format +msgid "1 grade partially updated (only composition, manual grade not changed)" +msgid_plural "%{count} grades partially updated (only compositions, manual grades not changed)" +msgstr[0] "1 nota parcialmente atualizada (apenas composição, nota manual não alterada)" +msgstr[1] "%{count} notas parcialmente atualizadas (apenas composições, notas manuais não alteradas)" + +#: lib/lanttern_web/components/grades_reports_components.ex:508 +#, elixir-autogen, elixir-format +msgid "There is a manual grade change that will be overwritten by this operation. Are you sure you want to proceed?" +msgstr "A nota atribuída manualmente será sobrescrita por esta operação. Você tem certeza que deseja proceder?" From ddaf3bdaa7264cf8c031f9e0404d6bd082898f48 Mon Sep 17 00:00:00 2001 From: endoooo Date: Thu, 20 Jun 2024 10:21:31 -0300 Subject: [PATCH 5/5] refactor: reduced cyclomatic complexity based on credo recommendations - refactored `handle_student_grades_report_entry_creation/7` (private fn in `GradesReports` context) - refactored `EntryEditorComponent`'s `"change"` `handle_event` --- lib/lanttern/grades_reports.ex | 62 +++++++------ .../assessments/entry_editor_component.ex | 88 +++++++++++-------- 2 files changed, 89 insertions(+), 61 deletions(-) diff --git a/lib/lanttern/grades_reports.ex b/lib/lanttern/grades_reports.ex index 56b41dc2..c91a3aaf 100644 --- a/lib/lanttern/grades_reports.ex +++ b/lib/lanttern/grades_reports.ex @@ -670,36 +670,48 @@ defmodule Lanttern.GradesReports do grades_report_cycle_id: grades_report_cycle_id, grades_report_subject_id: grades_report_subject_id ) - |> case do - nil -> - case create_student_grade_report_entry(attrs) do - {:ok, sgre} -> {:ok, sgre, :created} - error_tuple -> error_tuple - end + |> create_or_update_student_grade_report_entry(attrs, force_overwrite) + end - %{ordinal_value_id: ov_id, composition_ordinal_value_id: comp_ov_id} = sgre - when ov_id != comp_ov_id and not force_overwrite -> - attrs = Map.drop(attrs, [:ordinal_value_id]) + defp create_or_update_student_grade_report_entry(nil, attrs, _) do + case create_student_grade_report_entry(attrs) do + {:ok, sgre} -> {:ok, sgre, :created} + error_tuple -> error_tuple + end + end - case update_student_grade_report_entry(sgre, attrs) do - {:ok, sgre} -> {:ok, sgre, :updated_with_manual} - error_tuple -> error_tuple - end + defp create_or_update_student_grade_report_entry( + %{ordinal_value_id: ov_id, composition_ordinal_value_id: comp_ov_id} = sgre, + attrs, + false + ) + when ov_id != comp_ov_id do + attrs = Map.drop(attrs, [:ordinal_value_id]) - %{score: score, composition_score: comp_score} = sgre - when score != comp_score and not force_overwrite -> - attrs = Map.drop(attrs, [:score]) + case update_student_grade_report_entry(sgre, attrs) do + {:ok, sgre} -> {:ok, sgre, :updated_with_manual} + error_tuple -> error_tuple + end + end - case update_student_grade_report_entry(sgre, attrs) do - {:ok, sgre} -> {:ok, sgre, :updated_with_manual} - error_tuple -> error_tuple - end + defp create_or_update_student_grade_report_entry( + %{score: score, composition_score: comp_score} = sgre, + attrs, + false + ) + when score != comp_score do + attrs = Map.drop(attrs, [:score]) - sgre -> - case update_student_grade_report_entry(sgre, attrs) do - {:ok, sgre} -> {:ok, sgre, :updated} - error_tuple -> error_tuple - end + case update_student_grade_report_entry(sgre, attrs) do + {:ok, sgre} -> {:ok, sgre, :updated_with_manual} + error_tuple -> error_tuple + end + end + + defp create_or_update_student_grade_report_entry(sgre, attrs, _force_overwrite) do + case update_student_grade_report_entry(sgre, attrs) do + {:ok, sgre} -> {:ok, sgre, :updated} + error_tuple -> error_tuple end end diff --git a/lib/lanttern_web/live/shared/assessments/entry_editor_component.ex b/lib/lanttern_web/live/shared/assessments/entry_editor_component.ex index 680b1f91..30ee613c 100644 --- a/lib/lanttern_web/live/shared/assessments/entry_editor_component.ex +++ b/lib/lanttern_web/live/shared/assessments/entry_editor_component.ex @@ -197,7 +197,7 @@ defmodule LantternWeb.Assessments.EntryEditorComponent do @impl true def handle_event("change", %{"assessment_point_entry" => params}, socket) do %{ - entry: %{scale_type: scale_type} = entry, + entry: entry, assessment_view: assessment_view, entry_value: entry_value } = socket.assigns @@ -213,46 +213,21 @@ defmodule LantternWeb.Assessments.EntryEditorComponent do |> Map.take([:student_id, :assessment_point_id, :scale_id, :scale_type]) |> Map.new(fn {k, v} -> {to_string(k), v} end) - composite_id = "#{entry_params["student_id"]}_#{entry_params["assessment_point_id"]}" - # add extra fields from entry params = params |> Enum.into(entry_params) - param_value = - case {params, assessment_view} do - {%{"scale_type" => "ordinal"}, "student"} -> params["student_ordinal_value_id"] - {%{"scale_type" => "numeric"}, "student"} -> params["student_score"] - {%{"scale_type" => "ordinal"}, _teacher} -> params["ordinal_value_id"] - {%{"scale_type" => "numeric"}, _teacher} -> params["score"] - end - - # when in student view, other value - # is the teacher value (and vice versa) - other_entry_value = - case {scale_type, assessment_view} do - {"ordinal", "student"} -> entry.ordinal_value_id - {"numeric", "student"} -> entry.score - {"ordinal", _teacher} -> entry.student_ordinal_value_id - {"numeric", _teacher} -> entry.student_score - end + # get the right ordinal value or score based on view + param_value = get_param_value(params, assessment_view) - # types: new, delete, edit, cancel - {change_type, has_changes} = - case {entry.id, "#{entry_value}", other_entry_value, param_value} do - {_, entry_value, _, param_value} when entry_value == param_value -> - {:cancel, false} + # when in student view, other value = teacher value (and vice-versa) + other_entry_value = get_other_entry_value(entry, assessment_view) - {nil, _, _, param_value} when param_value != "" -> - {:new, true} + {has_changes, change_type} = + check_for_changes(entry.id, "#{entry_value}", other_entry_value, param_value) - {entry_id, _, nil, ""} when not is_nil(entry_id) -> - {:delete, true} - - _ -> - {:edit, true} - end + composite_id = "#{entry_params["student_id"]}_#{entry_params["assessment_point_id"]}" notify( __MODULE__, @@ -268,17 +243,14 @@ defmodule LantternWeb.Assessments.EntryEditorComponent do {:noreply, socket} end - @impl true def handle_event("edit_note", _, socket) do {:noreply, assign(socket, :is_editing_note, true)} end - @impl true def handle_event("cancel_edit_note", _, socket) do {:noreply, assign(socket, :is_editing_note, false)} end - @impl true def handle_event("save_note", %{"assessment_point_entry" => params}, socket) do opts = [log_profile_id: socket.assigns.current_user.current_profile_id] @@ -395,4 +367,48 @@ defmodule LantternWeb.Assessments.EntryEditorComponent do end defp get_colors_style(_), do: "" + + @spec get_param_value(params :: map(), view :: String.t()) :: String.t() + defp get_param_value(%{"scale_type" => "ordinal"} = params, "student"), + do: params["student_ordinal_value_id"] + + defp get_param_value(%{"scale_type" => "numeric"} = params, "student"), + do: params["student_score"] + + defp get_param_value(%{"scale_type" => "ordinal"} = params, _teacher), + do: params["ordinal_value_id"] + + defp get_param_value(%{"scale_type" => "numeric"} = params, _teacher), + do: params["score"] + + @spec get_other_entry_value(entry :: AssessmentPointEntry.t(), view :: String.t()) :: + float() | pos_integer() | nil + defp get_other_entry_value(%{scale_type: "ordinal"} = entry, "student"), + do: entry.ordinal_value_id + + defp get_other_entry_value(%{scale_type: "numeric"} = entry, "student"), + do: entry.score + + defp get_other_entry_value(%{scale_type: "ordinal"} = entry, _teacher), + do: entry.student_ordinal_value_id + + defp get_other_entry_value(%{scale_type: "numeric"} = entry, _teacher), + do: entry.student_score + + @spec check_for_changes( + entry_id :: pos_integer() | nil, + entry_value :: any(), + other_entry_value :: any(), + param_value :: String.t() + ) :: {boolean(), :cancel | :new | :delete | :edit} + defp check_for_changes(_, entry_value, _, param_value) when entry_value == param_value, + do: {false, :cancel} + + defp check_for_changes(nil, _, _, param_value) when param_value != "", + do: {true, :new} + + defp check_for_changes(entry_id, _, nil, "") when not is_nil(entry_id), + do: {true, :delete} + + defp check_for_changes(_, _, _, _), do: {true, :edit} end