1use utoipa::ToSchema;
10
11use crate::prelude::*;
12
13#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone, Copy, Type, ToSchema)]
15#[sqlx(
16 type_name = "credit_registration_enrolment_route",
17 rename_all = "snake_case"
18)]
19#[serde(rename_all = "snake_case")]
20pub enum CreditRegistrationEnrolmentRoute {
21 UniversityOfHelsinki,
22 OpenUniversity,
23}
24
25#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone, Copy, Type, ToSchema)]
27#[sqlx(type_name = "credit_registration_need", rename_all = "snake_case")]
28#[serde(rename_all = "snake_case")]
29pub enum CreditRegistrationNeed {
30 Certificate,
31 Credits,
32}
33
34#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone, Copy, Type, ToSchema)]
37#[sqlx(
38 type_name = "credit_registration_identification",
39 rename_all = "snake_case"
40)]
41#[serde(rename_all = "snake_case")]
42pub enum CreditRegistrationIdentification {
43 Eidas,
44 OtherSuomiFi,
45 #[sqlx(rename = "none")]
46 #[serde(rename = "none")]
47 NoSuomiFi,
48}
49
50#[derive(Debug, Serialize, Deserialize, PartialEq, Clone, ToSchema)]
55pub struct EnrolmentAnswers {
56 pub route: CreditRegistrationEnrolmentRoute,
57 pub has_finnish_personal_identity_code: Option<bool>,
58 pub need: Option<CreditRegistrationNeed>,
59 pub identification: Option<CreditRegistrationIdentification>,
60 pub need_after_reconsider: Option<CreditRegistrationNeed>,
62}
63
64#[derive(Debug, Serialize, Deserialize, PartialEq, Clone, ToSchema)]
65pub struct EnrolmentRouteAnswer {
66 pub course_module_completion_id: Uuid,
67 pub route: CreditRegistrationEnrolmentRoute,
68 pub has_finnish_personal_identity_code: Option<bool>,
69 pub need: Option<CreditRegistrationNeed>,
70 pub identification: Option<CreditRegistrationIdentification>,
71 pub need_after_reconsider: Option<CreditRegistrationNeed>,
72 pub enrolment_confirmed_at: Option<DateTime<Utc>>,
74 pub certificate_chosen_at: Option<DateTime<Utc>>,
77}
78
79pub async fn get_by_completion_id(
80 conn: &mut PgConnection,
81 course_module_completion_id: Uuid,
82) -> ModelResult<Option<EnrolmentRouteAnswer>> {
83 let res = sqlx::query_as!(
84 EnrolmentRouteAnswer,
85 r#"
86SELECT course_module_completion_id,
87 route AS "route: _",
88 has_finnish_personal_identity_code,
89 need AS "need: _",
90 identification AS "identification: _",
91 need_after_reconsider AS "need_after_reconsider: _",
92 enrolment_confirmed_at,
93 certificate_chosen_at
94FROM credit_registration_enrolment_routes
95WHERE course_module_completion_id = $1
96 AND deleted_at IS NULL
97 "#,
98 course_module_completion_id,
99 )
100 .fetch_optional(conn)
101 .await?;
102 Ok(res)
103}
104
105pub async fn set_answers(
110 conn: &mut PgConnection,
111 course_module_completion_id: Uuid,
112 user_id: Uuid,
113 answers: &EnrolmentAnswers,
114) -> ModelResult<EnrolmentRouteAnswer> {
115 let res = sqlx::query_as!(
116 EnrolmentRouteAnswer,
117 r#"
118INSERT INTO credit_registration_enrolment_routes (
119 course_module_completion_id,
120 user_id,
121 route,
122 has_finnish_personal_identity_code,
123 need,
124 identification,
125 need_after_reconsider
126 )
127VALUES ($1, $2, $3, $4, $5, $6, $7)
128ON CONFLICT (course_module_completion_id, deleted_at) DO
129UPDATE
130SET route = EXCLUDED.route,
131 has_finnish_personal_identity_code = EXCLUDED.has_finnish_personal_identity_code,
132 need = EXCLUDED.need,
133 identification = EXCLUDED.identification,
134 need_after_reconsider = EXCLUDED.need_after_reconsider,
135 enrolment_confirmed_at = CASE
136 WHEN credit_registration_enrolment_routes.route = EXCLUDED.route THEN credit_registration_enrolment_routes.enrolment_confirmed_at
137 ELSE NULL
138 END
139RETURNING course_module_completion_id,
140 route AS "route: _",
141 has_finnish_personal_identity_code,
142 need AS "need: _",
143 identification AS "identification: _",
144 need_after_reconsider AS "need_after_reconsider: _",
145 enrolment_confirmed_at,
146 certificate_chosen_at
147 "#,
148 course_module_completion_id,
149 user_id,
150 answers.route as CreditRegistrationEnrolmentRoute,
151 answers.has_finnish_personal_identity_code,
152 answers.need as Option<CreditRegistrationNeed>,
153 answers.identification as Option<CreditRegistrationIdentification>,
154 answers.need_after_reconsider as Option<CreditRegistrationNeed>,
155 )
156 .fetch_one(conn)
157 .await?;
158 Ok(res)
159}
160
161pub async fn set_enrolment_confirmed(
165 conn: &mut PgConnection,
166 course_module_completion_id: Uuid,
167 confirmed: bool,
168) -> ModelResult<EnrolmentRouteAnswer> {
169 let res = sqlx::query_as!(
170 EnrolmentRouteAnswer,
171 r#"
172UPDATE credit_registration_enrolment_routes
173SET enrolment_confirmed_at = CASE
174 WHEN $2 THEN COALESCE(enrolment_confirmed_at, now())
175 ELSE NULL
176 END
177WHERE course_module_completion_id = $1
178 AND deleted_at IS NULL
179RETURNING course_module_completion_id,
180 route AS "route: _",
181 has_finnish_personal_identity_code,
182 need AS "need: _",
183 identification AS "identification: _",
184 need_after_reconsider AS "need_after_reconsider: _",
185 enrolment_confirmed_at,
186 certificate_chosen_at
187 "#,
188 course_module_completion_id,
189 confirmed,
190 )
191 .fetch_one(conn)
192 .await?;
193 Ok(res)
194}
195
196pub async fn set_certificate_chosen(
200 conn: &mut PgConnection,
201 course_module_completion_id: Uuid,
202 chosen: bool,
203) -> ModelResult<EnrolmentRouteAnswer> {
204 let res = sqlx::query_as!(
205 EnrolmentRouteAnswer,
206 r#"
207UPDATE credit_registration_enrolment_routes
208SET certificate_chosen_at = CASE
209 WHEN $2 THEN COALESCE(certificate_chosen_at, now())
210 ELSE NULL
211 END
212WHERE course_module_completion_id = $1
213 AND deleted_at IS NULL
214RETURNING course_module_completion_id,
215 route AS "route: _",
216 has_finnish_personal_identity_code,
217 need AS "need: _",
218 identification AS "identification: _",
219 need_after_reconsider AS "need_after_reconsider: _",
220 enrolment_confirmed_at,
221 certificate_chosen_at
222 "#,
223 course_module_completion_id,
224 chosen,
225 )
226 .fetch_one(conn)
227 .await?;
228 Ok(res)
229}
230
231pub async fn delete_all_by_user_id(conn: &mut PgConnection, user_id: Uuid) -> ModelResult<()> {
234 sqlx::query!(
235 "
236DELETE FROM credit_registration_enrolment_routes
237WHERE user_id = $1
238 ",
239 user_id,
240 )
241 .execute(conn)
242 .await?;
243 Ok(())
244}