headless_lms_models/
course_instance_enrollments.rs1use crate::{
2 course_instances::CourseInstance, course_module_completions::CourseModuleCompletion,
3 courses::Course, prelude::*, user_course_settings::UserCourseSettings,
4};
5
6#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
7#[cfg_attr(feature = "ts_rs", derive(TS))]
8pub struct CourseInstanceEnrollment {
9 pub user_id: Uuid,
10 pub course_id: Uuid,
11 pub course_instance_id: Uuid,
12 pub created_at: DateTime<Utc>,
13 pub updated_at: DateTime<Utc>,
14 pub deleted_at: Option<DateTime<Utc>>,
15}
16
17#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
18#[cfg_attr(feature = "ts_rs", derive(TS))]
19pub struct CourseInstanceEnrollmentsInfo {
20 pub course_instance_enrollments: Vec<CourseInstanceEnrollment>,
21 pub course_instances: Vec<CourseInstance>,
22 pub courses: Vec<Course>,
23 pub user_course_settings: Vec<UserCourseSettings>,
24 pub course_module_completions: Vec<CourseModuleCompletion>,
25}
26
27pub async fn insert(
28 conn: &mut PgConnection,
29 user_id: Uuid,
30 course_id: Uuid,
31 course_instance_id: Uuid,
32) -> ModelResult<()> {
33 sqlx::query!(
34 "
35INSERT INTO course_instance_enrollments (user_id, course_id, course_instance_id)
36VALUES ($1, $2, $3)
37",
38 user_id,
39 course_id,
40 course_instance_id,
41 )
42 .execute(conn)
43 .await?;
44 Ok(())
45}
46
47#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
48pub struct NewCourseInstanceEnrollment {
49 pub user_id: Uuid,
50 pub course_id: Uuid,
51 pub course_instance_id: Uuid,
52}
53
54pub async fn insert_enrollment_if_it_doesnt_exist(
60 conn: &mut PgConnection,
61 enrollment: NewCourseInstanceEnrollment,
62) -> ModelResult<CourseInstanceEnrollment> {
63 let enrollment = sqlx::query_as!(
64 CourseInstanceEnrollment,
65 "
66INSERT INTO course_instance_enrollments (user_id, course_id, course_instance_id)
67VALUES ($1, $2, $3)
68ON CONFLICT (user_id, course_instance_id)
69DO UPDATE SET deleted_at = NULL
70RETURNING *;
71",
72 enrollment.user_id,
73 enrollment.course_id,
74 enrollment.course_instance_id,
75 )
76 .fetch_one(conn)
77 .await?;
78 Ok(enrollment)
79}
80
81pub async fn insert_enrollment_and_set_as_current(
82 conn: &mut PgConnection,
83 new_enrollment: NewCourseInstanceEnrollment,
84) -> ModelResult<CourseInstanceEnrollment> {
85 let mut tx = conn.begin().await?;
86
87 let enrollment = insert_enrollment_if_it_doesnt_exist(&mut tx, new_enrollment).await?;
88 crate::user_course_settings::upsert_user_course_settings_for_enrollment(&mut tx, &enrollment)
89 .await?;
90 tx.commit().await?;
91
92 Ok(enrollment)
93}
94
95pub async fn get_by_user_and_course_instance_id(
96 conn: &mut PgConnection,
97 user_id: Uuid,
98 course_instance_id: Uuid,
99) -> ModelResult<CourseInstanceEnrollment> {
100 let res = sqlx::query_as!(
101 CourseInstanceEnrollment,
102 "
103SELECT *
104FROM course_instance_enrollments
105WHERE user_id = $1
106 AND course_instance_id = $2
107 AND deleted_at IS NULL
108 ",
109 user_id,
110 course_instance_id
111 )
112 .fetch_one(conn)
113 .await?;
114 Ok(res)
115}
116
117pub async fn get_by_user_id(
118 conn: &mut PgConnection,
119 user_id: Uuid,
120) -> ModelResult<Vec<CourseInstanceEnrollment>> {
121 let res = sqlx::query_as!(
122 CourseInstanceEnrollment,
123 "
124SELECT *
125FROM course_instance_enrollments
126WHERE user_id = $1
127 AND deleted_at IS NULL
128 ",
129 user_id
130 )
131 .fetch_all(conn)
132 .await?;
133 Ok(res)
134}
135
136pub async fn get_course_instance_enrollments_info_for_user(
137 conn: &mut PgConnection,
138 user_id: Uuid,
139) -> ModelResult<CourseInstanceEnrollmentsInfo> {
140 let course_instance_enrollments = get_by_user_id(conn, user_id).await?;
141
142 let course_instance_ids: Vec<Uuid> = course_instance_enrollments
143 .iter()
144 .map(|e| e.course_instance_id)
145 .collect();
146
147 let course_instances = crate::course_instances::get_by_ids(conn, &course_instance_ids).await?;
148
149 let course_ids: Vec<Uuid> = course_instances.iter().map(|e| e.course_id).collect();
150
151 let courses = crate::courses::get_by_ids(conn, &course_ids).await?;
152
153 let course_module_completions =
154 crate::course_module_completions::get_all_by_user_id(conn, user_id).await?;
155
156 let user_course_settings =
158 crate::user_course_settings::get_all_by_user_and_multiple_current_courses(
159 conn,
160 &course_ids,
161 user_id,
162 )
163 .await?;
164
165 Ok(CourseInstanceEnrollmentsInfo {
166 course_instance_enrollments,
167 course_instances,
168 courses,
169 user_course_settings,
170 course_module_completions,
171 })
172}