headless_lms_models/library/credit_registration/
submission_context.rs1use std::collections::HashMap;
5
6use crate::prelude::*;
7
8use super::payload::CompletionFacts;
9
10#[derive(Debug, Clone, PartialEq)]
12pub struct SubmissionContext {
13 pub registration_id: Uuid,
14 pub student_number: Option<String>,
16 pub sisu_person_id: Option<String>,
17 pub uh_course_code: Option<String>,
18 pub ects_credits: Option<f32>,
19 pub configured_grade_scale_id: Option<String>,
20 pub configured_realisation_ids: Vec<String>,
22 pub completion: CompletionFacts,
23}
24
25pub async fn get_submission_contexts(
27 conn: &mut PgConnection,
28 registration_ids: &[Uuid],
29) -> ModelResult<HashMap<Uuid, SubmissionContext>> {
30 let rows = sqlx::query!(
31 r#"
32-- Nullability is stated for the outer-joined columns rather than inferred: sqlx-cli 0.9.0 derives
33-- them the wrong way round, and an offline build of this query then fails to compile.
34SELECT cr.id,
35 vsn.student_number AS "student_number?",
36 vsn.sisu_person_id AS "sisu_person_id?",
37 cm.uh_course_code,
38 cm.ects_credits,
39 conf.grade_scale_id AS "configured_grade_scale_id?",
40 COALESCE(
41 ARRAY_AGG(realisation.course_unit_realisation_id) FILTER (
42 WHERE realisation.id IS NOT NULL
43 ),
44 '{}'
45 ) AS "configured_realisation_ids!: Vec<String>",
46 cmc.passed,
47 cmc.grade,
48 cmc.completion_date,
49 cmc.completion_language
50FROM credit_registrations cr
51 JOIN course_module_completions cmc ON cmc.id = cr.course_module_completion_id
52 AND cmc.deleted_at IS NULL
53 JOIN course_modules cm ON cm.id = cr.course_module_id
54 AND cm.deleted_at IS NULL
55 LEFT JOIN verified_student_numbers vsn ON vsn.user_id = cr.user_id
56 AND vsn.deleted_at IS NULL
57 LEFT JOIN course_module_suotar_configurations conf ON conf.course_module_id = cr.course_module_id
58 AND conf.deleted_at IS NULL
59 LEFT JOIN course_module_suotar_realisations realisation ON realisation.course_module_id = cr.course_module_id
60 AND realisation.active
61 AND realisation.deleted_at IS NULL
62WHERE cr.id = ANY($1::uuid [])
63 AND cr.deleted_at IS NULL
64GROUP BY cr.id,
65 vsn.student_number,
66 vsn.sisu_person_id,
67 cm.uh_course_code,
68 cm.ects_credits,
69 conf.grade_scale_id,
70 cmc.passed,
71 cmc.grade,
72 cmc.completion_date,
73 cmc.completion_language
74 "#,
75 registration_ids,
76 )
77 .fetch_all(conn)
78 .await?;
79 Ok(rows
80 .into_iter()
81 .map(|row| {
82 (
83 row.id,
84 SubmissionContext {
85 registration_id: row.id,
86 student_number: row.student_number,
87 sisu_person_id: row.sisu_person_id,
88 uh_course_code: row.uh_course_code,
89 ects_credits: row.ects_credits,
90 configured_grade_scale_id: row.configured_grade_scale_id,
91 configured_realisation_ids: row.configured_realisation_ids,
92 completion: CompletionFacts {
93 passed: row.passed,
94 grade: row.grade,
95 completion_date: row.completion_date,
96 completion_language: row.completion_language,
97 },
98 },
99 )
100 })
101 .collect())
102}