Skip to content

Commit

Permalink
Merge pull request #244 from avantifellows/feat/treat-grade-as-group
Browse files Browse the repository at this point in the history
Feat: Treat grade as a group
  • Loading branch information
Bahugunajii authored Jan 20, 2025
2 parents 4437221 + 0ff433a commit e7e3505
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 0 deletions.
2 changes: 2 additions & 0 deletions lib/dbservice/grades.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ defmodule Dbservice.Grades do
alias Dbservice.Repo

alias Dbservice.Grades.Grade
alias Dbservice.Groups.Group

@doc """
Returns the list of grade.
Expand Down Expand Up @@ -59,6 +60,7 @@ defmodule Dbservice.Grades do
def create_grade(attrs \\ %{}) do
%Grade{}
|> Grade.changeset(attrs)
|> Ecto.Changeset.put_assoc(:group, [%Group{type: "grade", child_id: attrs["id"]}])
|> Repo.insert()
end

Expand Down
8 changes: 8 additions & 0 deletions lib/dbservice/grades/grade.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ defmodule Dbservice.Grades.Grade do
alias Dbservice.Tags.Tag
alias Dbservice.Chapters.Chapter
alias Dbservice.Topics.Topic
alias Dbservice.Groups.Group
alias Dbservice.EnrollmentRecords.EnrollmentRecord

schema "grade" do
field(:number, :integer)
Expand All @@ -16,6 +18,12 @@ defmodule Dbservice.Grades.Grade do
has_many(:chapter, Chapter)
has_many(:topic, Topic)
belongs_to(:tag, Tag)
has_many(:group, Group, foreign_key: :child_id, where: [type: "grade"])

has_many(:enrollment_record, EnrollmentRecord,
foreign_key: :group_id,
where: [group_type: "group"]
)
end

@doc false
Expand Down
12 changes: 12 additions & 0 deletions lib/dbservice_web/views/group_view.ex
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
defmodule DbserviceWeb.GroupView do
alias DbserviceWeb.GradeView
alias DbserviceWeb.SchoolView
alias Dbservice.Schools.School
use DbserviceWeb, :view
alias DbserviceWeb.GroupView
alias DbserviceWeb.AuthGroupView
alias DbserviceWeb.ProgramView
alias DbserviceWeb.BatchView
alias DbserviceWeb.GradeView
alias Dbservice.Repo
alias Dbservice.Groups.AuthGroup
alias Dbservice.Batches.Batch
alias Dbservice.Programs.Program
alias Dbservice.Grades.Grade

def render("index.json", %{group: group}) do
render_many(group, GroupView, "group.json")
Expand Down Expand Up @@ -57,6 +60,15 @@ defmodule DbserviceWeb.GroupView do
child_id: render_one(school, SchoolView, "school.json")
}

"grade" ->
grade = Repo.get!(Grade, group.child_id)

%{
id: group.id,
type: group.type,
child_id: render_one(grade, GradeView, "grade.json")
}

_ ->
%{
id: group.id,
Expand Down
117 changes: 117 additions & 0 deletions priv/repo/migrations/20250104114947_add_grade_to_enrollment_record.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
defmodule Dbservice.Repo.Migrations.AddGradeToEnrollmentRecord do
use Ecto.Migration

def change do
# First create entries in group table for grades
execute """
INSERT INTO "group" (type, child_id, inserted_at, updated_at)
SELECT DISTINCT 'grade' as type, g.id as child_id, NOW(), NOW()
FROM grade g
WHERE NOT EXISTS (
SELECT 1 FROM "group" WHERE type = 'grade' AND child_id = g.id
);
"""

# Create corresponding group_user entries - modified to only include latest grade
execute """
WITH latest_grade_enrollments AS (
SELECT DISTINCT ON (er.user_id)
er.user_id,
gr.id as grade_id,
er.inserted_at
FROM enrollment_record er
JOIN grade gr ON gr.id = er.grade_id
WHERE er.grade_id IS NOT NULL
ORDER BY er.user_id, er.inserted_at DESC
),
grade_users AS (
SELECT
lge.user_id,
g.id as group_id
FROM latest_grade_enrollments lge
JOIN "group" g ON g.type = 'grade' AND g.child_id = lge.grade_id
)
INSERT INTO group_user (
user_id,
group_id,
inserted_at,
updated_at
)
SELECT
user_id,
group_id,
NOW(),
NOW()
FROM grade_users
WHERE NOT EXISTS (
SELECT 1 FROM group_user gu
WHERE gu.user_id = grade_users.user_id
AND gu.group_id = grade_users.group_id
)
"""

# Create grade enrollment records
execute("""
WITH ranked_enrollments AS (
SELECT
er.user_id,
g.id AS group_id,
'grade' AS group_type,
er.academic_year,
er.start_date,
er.inserted_at,
ROW_NUMBER() OVER (PARTITION BY er.user_id, g.id ORDER BY er.inserted_at ASC) AS start_rank,
-- Get latest non-status record for end_date and is_current
FIRST_VALUE(er.end_date) OVER (
PARTITION BY er.user_id, g.id
ORDER BY
CASE WHEN er.group_type != 'status' THEN 0 ELSE 1 END,
er.inserted_at DESC
) AS latest_end_date,
FIRST_VALUE(er.is_current) OVER (
PARTITION BY er.user_id, g.id
ORDER BY
CASE WHEN er.group_type != 'status' THEN 0 ELSE 1 END,
er.inserted_at DESC
) AS latest_is_current
FROM enrollment_record er
JOIN grade g ON g.id = er.grade_id
WHERE er.grade_id IS NOT NULL
),
grade_enrollments AS (
SELECT
user_id,
group_id,
group_type,
academic_year,
MIN(start_date) FILTER (WHERE start_rank = 1) AS start_date,
MAX(latest_end_date) AS end_date,
bool_or(latest_is_current) AS is_current
FROM ranked_enrollments
GROUP BY user_id, group_id, group_type, academic_year
)
INSERT INTO enrollment_record (
user_id,
group_id,
group_type,
academic_year,
start_date,
end_date,
is_current,
inserted_at,
updated_at
)
SELECT
user_id,
group_id,
group_type,
academic_year,
start_date,
end_date,
is_current,
NOW(),
NOW()
FROM grade_enrollments;
""")
end
end

0 comments on commit e7e3505

Please sign in to comment.