headless_lms_models/course_module_suotar_configurations/
config_check.rs1use crate::prelude::*;
5
6#[derive(Debug, Clone, PartialEq)]
9pub struct SuotarModuleConfigFacts {
10 pub course_module_id: Uuid,
11 pub course_id: Uuid,
12 pub uh_course_code: Option<String>,
13 pub ects_credits: Option<f32>,
14 pub stored_course_code_allowed: Option<bool>,
17 pub stored_course_code_rejection: Option<String>,
18}
19
20pub async fn get_config_facts_for_modules_with_course_code(
24 conn: &mut PgConnection,
25 course_id: Option<Uuid>,
26) -> ModelResult<Vec<SuotarModuleConfigFacts>> {
27 let res = sqlx::query_as!(
28 SuotarModuleConfigFacts,
29 r#"
30SELECT cm.id AS "course_module_id!",
31 cm.course_id AS "course_id!",
32 cm.uh_course_code,
33 cm.ects_credits,
34 CASE
35 WHEN c.checked_course_code = TRIM(cm.uh_course_code) THEN c.course_code_allowed
36 END AS "stored_course_code_allowed?",
37 CASE
38 WHEN c.checked_course_code = TRIM(cm.uh_course_code) THEN c.course_code_rejection
39 END AS "stored_course_code_rejection?"
40FROM course_modules cm
41 LEFT JOIN course_module_suotar_configurations c ON c.course_module_id = cm.id
42 AND c.deleted_at IS NULL
43WHERE cm.deleted_at IS NULL
44 AND TRIM(cm.uh_course_code) <> ''
45 AND cm.completions_can_be_registered_to_sisu
46 AND ($1::uuid IS NULL OR cm.course_id = $1)
47ORDER BY cm.course_id,
48 cm.order_number
49 "#,
50 course_id,
51 )
52 .fetch_all(conn)
53 .await?;
54 Ok(res)
55}
56
57pub async fn count_modules_failing_config_check(conn: &mut PgConnection) -> ModelResult<i64> {
67 Ok(get_module_ids_failing_config_check(conn).await?.len() as i64)
68}
69
70pub async fn get_module_ids_failing_config_check(
72 conn: &mut PgConnection,
73) -> ModelResult<Vec<Uuid>> {
74 let ids = sqlx::query_scalar!(
75 r#"
76SELECT conf.course_module_id
77FROM course_module_suotar_configurations conf
78 JOIN course_modules cm ON cm.id = conf.course_module_id AND cm.deleted_at IS NULL
79WHERE TRIM(cm.uh_course_code) <> ''
80 AND cm.completions_can_be_registered_to_sisu
81 AND conf.deleted_at IS NULL
82 AND conf.config_checked_at IS NOT NULL
83 AND conf.config_check_message IS NOT NULL
84 "#,
85 )
86 .fetch_all(conn)
87 .await?;
88 Ok(ids)
89}
90
91#[derive(Debug, Clone, PartialEq, Default)]
94pub struct SuotarConfigCheck {
95 pub course_code_allowed: Option<bool>,
96 pub checked_course_code: Option<String>,
98 pub course_code_rejection: Option<String>,
99 pub message: Option<String>,
101}
102
103pub async fn record_config_check(
110 conn: &mut PgConnection,
111 course_module_id: Uuid,
112 check: &SuotarConfigCheck,
113) -> ModelResult<()> {
114 sqlx::query!(
115 r#"
116INSERT INTO course_module_suotar_configurations (
117 course_module_id,
118 config_checked_at,
119 course_code_allowed,
120 config_check_message,
121 checked_course_code,
122 course_code_rejection
123 )
124VALUES ($1, now(), $2, $3, $4, $5) ON CONFLICT (course_module_id) DO
125UPDATE
126SET config_checked_at = now(),
127 course_code_allowed = $2,
128 config_check_message = $3,
129 checked_course_code = $4,
130 course_code_rejection = $5,
131 deleted_at = NULL
132 "#,
133 course_module_id,
134 check.course_code_allowed,
135 check.message,
136 check.checked_course_code,
137 check.course_code_rejection,
138 )
139 .execute(conn)
140 .await?;
141 Ok(())
142}