| 1 |
|
|---|
| 2 | -- FOR v_student_registration_state VIEW
|
|---|
| 3 | CREATE OR REPLACE FUNCTION fn_student_registration_state(p_student_id INTEGER)
|
|---|
| 4 | RETURNS TABLE (
|
|---|
| 5 | student_id INTEGER,
|
|---|
| 6 | academic_program_code TEXT,
|
|---|
| 7 | course_code TEXT,
|
|---|
| 8 | course_name TEXT,
|
|---|
| 9 | credits INTEGER,
|
|---|
| 10 | mandatory BOOLEAN,
|
|---|
| 11 | curriculum_semester SMALLINT,
|
|---|
| 12 | already_passed BOOLEAN,
|
|---|
| 13 | currently_enrolled BOOLEAN,
|
|---|
| 14 | prerequisites_met BOOLEAN,
|
|---|
| 15 | missing_prereq_count BIGINT,
|
|---|
| 16 | credit_headroom BIGINT,
|
|---|
| 17 | would_exceed_cap BOOLEAN,
|
|---|
| 18 | can_enroll BOOLEAN,
|
|---|
| 19 | enrollment_status TEXT
|
|---|
| 20 | )
|
|---|
| 21 | LANGUAGE plpgsql STABLE
|
|---|
| 22 | AS $$
|
|---|
| 23 | BEGIN
|
|---|
| 24 | RETURN QUERY
|
|---|
| 25 | WITH
|
|---|
| 26 | active_pe AS (
|
|---|
| 27 | SELECT pe.id AS pe_id, pe.academic_program_code
|
|---|
| 28 | FROM Program_Enrollment pe
|
|---|
| 29 | WHERE pe.student_id = p_student_id
|
|---|
| 30 | AND pe.date_disenrollment IS NULL
|
|---|
| 31 | AND pe.finished IS NOT TRUE
|
|---|
| 32 | ),
|
|---|
| 33 | passed_courses AS (
|
|---|
| 34 | SELECT DISTINCT ed.course_code AS passed_code
|
|---|
| 35 | FROM active_pe ape
|
|---|
| 36 | JOIN Semester_Enrollment se ON se.program_enrollment_id = ape.pe_id
|
|---|
| 37 | JOIN Course_Enrollment ce ON ce.semester_enrollment_id = se.id
|
|---|
| 38 | JOIN Course_Edition ed ON ed.id = ce.course_edition_id
|
|---|
| 39 | JOIN Student_Grade sg ON sg.course_enrollment_id = ce.id
|
|---|
| 40 | ),
|
|---|
| 41 | passed_with_equiv AS (
|
|---|
| 42 | SELECT passed_code FROM passed_courses
|
|---|
| 43 | UNION
|
|---|
| 44 | SELECT eq.course2_code
|
|---|
| 45 | FROM passed_courses pc
|
|---|
| 46 | JOIN Course_Equivalence eq ON eq.course1_code = pc.passed_code
|
|---|
| 47 | UNION
|
|---|
| 48 | SELECT eq.course1_code
|
|---|
| 49 | FROM passed_courses pc
|
|---|
| 50 | JOIN Course_Equivalence eq ON eq.course2_code = pc.passed_code
|
|---|
| 51 | ),
|
|---|
| 52 | current_enrollments AS (
|
|---|
| 53 | SELECT ed.course_code AS curr_code
|
|---|
| 54 | FROM active_pe ape
|
|---|
| 55 | JOIN Semester_Enrollment se ON se.program_enrollment_id = ape.pe_id
|
|---|
| 56 | AND se.academic_year = 2025 AND (se.semester::int) = 1 -- cast to int, compare to 1
|
|---|
| 57 | JOIN Course_Enrollment ce ON ce.semester_enrollment_id = se.id
|
|---|
| 58 | JOIN Course_Edition ed ON ed.id = ce.course_edition_id
|
|---|
| 59 | ),
|
|---|
| 60 | current_credits AS (
|
|---|
| 61 | SELECT COALESCE(SUM(c.credits), 0) AS credits_consumed
|
|---|
| 62 | FROM active_pe ape
|
|---|
| 63 | LEFT JOIN Semester_Enrollment se ON se.program_enrollment_id = ape.pe_id
|
|---|
| 64 | AND se.academic_year = 2025 AND (se.semester::int) = 1
|
|---|
| 65 | LEFT JOIN Course_Enrollment ce ON ce.semester_enrollment_id = se.id
|
|---|
| 66 | LEFT JOIN Course_Edition ed ON ed.id = ce.course_edition_id
|
|---|
| 67 | LEFT JOIN Course c ON c.code = ed.course_code
|
|---|
| 68 | ),
|
|---|
| 69 | prereq_check AS (
|
|---|
| 70 | SELECT
|
|---|
| 71 | cur.course_code AS prereq_course,
|
|---|
| 72 | COUNT(cp.predecessor_course_code) AS total_prereqs,
|
|---|
| 73 | COUNT(pwe.passed_code) AS met_prereqs
|
|---|
| 74 | FROM active_pe ape
|
|---|
| 75 | CROSS JOIN Curriculum cur
|
|---|
| 76 | LEFT JOIN Course_Prerequisite cp ON cp.successor_course_code = cur.course_code
|
|---|
| 77 | LEFT JOIN passed_with_equiv pwe ON pwe.passed_code = cp.predecessor_course_code
|
|---|
| 78 | WHERE cur.academic_program_code = ape.academic_program_code
|
|---|
| 79 | GROUP BY cur.course_code
|
|---|
| 80 | )
|
|---|
| 81 | SELECT
|
|---|
| 82 | p_student_id,
|
|---|
| 83 | ape.academic_program_code,
|
|---|
| 84 | cur.course_code,
|
|---|
| 85 | c.name,
|
|---|
| 86 | c.credits,
|
|---|
| 87 | cur.mandatory,
|
|---|
| 88 | cur.semester,
|
|---|
| 89 | (pwe.passed_code IS NOT NULL) AS already_passed,
|
|---|
| 90 | (ce_now.curr_code IS NOT NULL) AS currently_enrolled,
|
|---|
| 91 | COALESCE(pc.total_prereqs IS NULL OR pc.met_prereqs = pc.total_prereqs, TRUE) AS prerequisites_met,
|
|---|
| 92 | COALESCE(pc.total_prereqs - pc.met_prereqs, 0) AS missing_prereq_count,
|
|---|
| 93 | 40 - cc.credits_consumed AS credit_headroom,
|
|---|
| 94 | (40 - cc.credits_consumed) < c.credits AS would_exceed_cap,
|
|---|
| 95 | CASE
|
|---|
| 96 | WHEN pwe.passed_code IS NOT NULL THEN FALSE
|
|---|
| 97 | WHEN ce_now.curr_code IS NOT NULL THEN FALSE
|
|---|
| 98 | WHEN pc.total_prereqs IS NOT NULL AND pc.met_prereqs < pc.total_prereqs THEN FALSE
|
|---|
| 99 | WHEN (40 - cc.credits_consumed) < c.credits THEN FALSE
|
|---|
| 100 | ELSE TRUE
|
|---|
| 101 | END AS can_enroll,
|
|---|
| 102 | CASE
|
|---|
| 103 | WHEN pwe.passed_code IS NOT NULL THEN 'already_passed'
|
|---|
| 104 | WHEN ce_now.curr_code IS NOT NULL THEN 'currently_enrolled'
|
|---|
| 105 | WHEN pc.total_prereqs IS NOT NULL AND pc.met_prereqs < pc.total_prereqs THEN 'prerequisites_not_met'
|
|---|
| 106 | WHEN (40 - cc.credits_consumed) < c.credits THEN 'credit_cap_exceeded'
|
|---|
| 107 | ELSE 'eligible'
|
|---|
| 108 | END AS enrollment_status
|
|---|
| 109 | FROM active_pe ape
|
|---|
| 110 | CROSS JOIN Curriculum cur
|
|---|
| 111 | JOIN Course c ON c.code = cur.course_code
|
|---|
| 112 | LEFT JOIN passed_with_equiv pwe ON pwe.passed_code = cur.course_code
|
|---|
| 113 | LEFT JOIN current_enrollments ce_now ON ce_now.curr_code = cur.course_code
|
|---|
| 114 | LEFT JOIN prereq_check pc ON pc.prereq_course = cur.course_code
|
|---|
| 115 | CROSS JOIN current_credits cc
|
|---|
| 116 | WHERE cur.academic_program_code = ape.academic_program_code;
|
|---|
| 117 | END;
|
|---|
| 118 | $$;
|
|---|
| 119 |
|
|---|
| 120 |
|
|---|
| 121 |
|
|---|
| 122 |
|
|---|
| 123 |
|
|---|
| 124 | -- FOR v_teaching_assistant_eligibility VIEW
|
|---|
| 125 | CREATE OR REPLACE FUNCTION fn_teaching_assistant_eligibility(p_edition_id INTEGER)
|
|---|
| 126 | RETURNS TABLE (
|
|---|
| 127 | student_id INTEGER,
|
|---|
| 128 | student_index TEXT,
|
|---|
| 129 | student_name TEXT,
|
|---|
| 130 | edition_id INTEGER,
|
|---|
| 131 | academic_year SMALLINT,
|
|---|
| 132 | semester SMALLINT,
|
|---|
| 133 | course_code TEXT,
|
|---|
| 134 | course_name TEXT,
|
|---|
| 135 | eligible_supervisors TEXT,
|
|---|
| 136 | times_enrolled BIGINT
|
|---|
| 137 | )
|
|---|
| 138 | LANGUAGE plpgsql STABLE
|
|---|
| 139 | AS $$
|
|---|
| 140 | DECLARE
|
|---|
| 141 | var_course_code TEXT;
|
|---|
| 142 | var_academic_year SMALLINT;
|
|---|
| 143 | var_semester SMALLINT;
|
|---|
| 144 | BEGIN
|
|---|
| 145 | SELECT ed.course_code, ed.academic_year, ed.semester
|
|---|
| 146 | INTO var_course_code, var_academic_year, var_semester
|
|---|
| 147 | FROM Course_Edition ed
|
|---|
| 148 | WHERE ed.id = p_edition_id;
|
|---|
| 149 |
|
|---|
| 150 | IF NOT FOUND THEN
|
|---|
| 151 | RETURN;
|
|---|
| 152 | END IF;
|
|---|
| 153 |
|
|---|
| 154 | RETURN QUERY
|
|---|
| 155 | WITH
|
|---|
| 156 | course_passers AS (
|
|---|
| 157 | SELECT DISTINCT pe.student_id
|
|---|
| 158 | FROM Program_Enrollment pe
|
|---|
| 159 | JOIN Semester_Enrollment se ON se.program_enrollment_id = pe.id
|
|---|
| 160 | JOIN Course_Enrollment ce ON ce.semester_enrollment_id = se.id
|
|---|
| 161 | JOIN Course_Edition ed ON ed.id = ce.course_edition_id
|
|---|
| 162 | JOIN Student_Grade sg ON sg.course_enrollment_id = ce.id
|
|---|
| 163 | WHERE ed.course_code = var_course_code
|
|---|
| 164 | ),
|
|---|
| 165 | currently_enrolled AS (
|
|---|
| 166 | SELECT DISTINCT pe.student_id
|
|---|
| 167 | FROM Program_Enrollment pe
|
|---|
| 168 | JOIN Semester_Enrollment se ON se.program_enrollment_id = pe.id
|
|---|
| 169 | AND se.academic_year = var_academic_year
|
|---|
| 170 | AND (se.semester::int) = var_semester -- compare to SMALLINT variable, cast semester to int
|
|---|
| 171 | JOIN Course_Enrollment ce ON ce.semester_enrollment_id = se.id
|
|---|
| 172 | WHERE ce.course_edition_id = p_edition_id
|
|---|
| 173 | ),
|
|---|
| 174 | existing_tas AS (
|
|---|
| 175 | SELECT ta.student_id
|
|---|
| 176 | FROM Teaching_Assistant ta
|
|---|
| 177 | JOIN Teaches tt ON tt.teacher_id = ta.teacher_id
|
|---|
| 178 | WHERE tt.course_edition_id = p_edition_id
|
|---|
| 179 | ),
|
|---|
| 180 | supervisors AS (
|
|---|
| 181 | SELECT STRING_AGG(m.name || ' ' || m.surname, ', ' ORDER BY m.surname) AS names
|
|---|
| 182 | FROM Teaches t
|
|---|
| 183 | JOIN Member m ON m.id = t.teacher_id
|
|---|
| 184 | WHERE t.course_edition_id = p_edition_id
|
|---|
| 185 | ),
|
|---|
| 186 | times_taken AS (
|
|---|
| 187 | SELECT
|
|---|
| 188 | pe.student_id,
|
|---|
| 189 | COUNT(DISTINCT ce.id) AS cnt
|
|---|
| 190 | FROM Program_Enrollment pe
|
|---|
| 191 | JOIN Semester_Enrollment se ON se.program_enrollment_id = pe.id
|
|---|
| 192 | JOIN Course_Enrollment ce ON ce.semester_enrollment_id = se.id
|
|---|
| 193 | JOIN Course_Edition ed ON ed.id = ce.course_edition_id
|
|---|
| 194 | WHERE ed.course_code = var_course_code
|
|---|
| 195 | GROUP BY pe.student_id
|
|---|
| 196 | )
|
|---|
| 197 | SELECT
|
|---|
| 198 | s.id,
|
|---|
| 199 | s.index,
|
|---|
| 200 | m.name || ' ' || m.surname,
|
|---|
| 201 | p_edition_id,
|
|---|
| 202 | var_academic_year,
|
|---|
| 203 | var_semester,
|
|---|
| 204 | c.code,
|
|---|
| 205 | c.name,
|
|---|
| 206 | supervisors.names,
|
|---|
| 207 | COALESCE(times_taken.cnt, 0)::BIGINT
|
|---|
| 208 | FROM course_passers cp
|
|---|
| 209 | JOIN Student s ON s.id = cp.student_id
|
|---|
| 210 | JOIN Member m ON m.id = s.id
|
|---|
| 211 | CROSS JOIN Course c
|
|---|
| 212 | CROSS JOIN supervisors
|
|---|
| 213 | LEFT JOIN currently_enrolled ce ON ce.student_id = cp.student_id
|
|---|
| 214 | LEFT JOIN existing_tas et ON et.student_id = cp.student_id
|
|---|
| 215 | LEFT JOIN times_taken ON times_taken.student_id = cp.student_id
|
|---|
| 216 | WHERE ce.student_id IS NULL
|
|---|
| 217 | AND et.student_id IS NULL
|
|---|
| 218 | AND c.code = var_course_code;
|
|---|
| 219 | END;
|
|---|
| 220 | $$; |
|---|