headless_lms_server/controllers/main_frontend/
code_giveaways.rs1use chrono::Utc;
3use domain::csv_export::{code_giveaway_codes::CodeGiveawayCodesExportOperation, general_export};
4use headless_lms_models::{
5 code_giveaway_codes::CodeGiveawayCode,
6 code_giveaways::{CodeGiveaway, NewCodeGiveaway},
7};
8
9use crate::prelude::*;
10
11#[instrument(skip(pool))]
15async fn get_code_giveaways_by_course(
16 pool: web::Data<PgPool>,
17 course_id: web::Path<Uuid>,
18 user: AuthUser,
19) -> ControllerResult<web::Json<Vec<CodeGiveaway>>> {
20 let mut conn = pool.acquire().await?;
21
22 let token = authorize(&mut conn, Act::Edit, Some(user.id), Res::Course(*course_id)).await?;
23
24 let code_giveaways = models::code_giveaways::get_all_for_course(&mut conn, *course_id).await?;
25
26 token.authorized_ok(web::Json(code_giveaways))
27}
28
29#[instrument(skip(pool))]
33async fn create_code_giveaway(
34 pool: web::Data<PgPool>,
35 code_giveaway: web::Json<NewCodeGiveaway>,
36 user: AuthUser,
37) -> ControllerResult<web::Json<CodeGiveaway>> {
38 let mut conn = pool.acquire().await?;
39
40 let token = authorize(
41 &mut conn,
42 Act::Edit,
43 Some(user.id),
44 Res::Course(code_giveaway.course_id),
45 )
46 .await?;
47
48 let code_giveaway = models::code_giveaways::insert(&mut conn, &code_giveaway).await?;
49
50 token.authorized_ok(web::Json(code_giveaway))
51}
52
53#[instrument(skip(pool))]
57async fn get_code_giveaway_by_id(
58 pool: web::Data<PgPool>,
59 id: web::Path<Uuid>,
60 user: AuthUser,
61) -> ControllerResult<web::Json<CodeGiveaway>> {
62 let mut conn = pool.acquire().await?;
63
64 let code_giveaway = models::code_giveaways::get_by_id(&mut conn, *id).await?;
65
66 let token = authorize(
67 &mut conn,
68 Act::Edit,
69 Some(user.id),
70 Res::Course(code_giveaway.course_id),
71 )
72 .await?;
73
74 token.authorized_ok(web::Json(code_giveaway))
75}
76
77#[instrument(skip(pool))]
81async fn add_codes_to_code_giveaway(
82 pool: web::Data<PgPool>,
83 id: web::Path<Uuid>,
84 codes: web::Json<Vec<String>>,
85 user: AuthUser,
86) -> ControllerResult<web::Json<Vec<CodeGiveawayCode>>> {
87 let mut conn = pool.acquire().await?;
88
89 let code_giveaway = models::code_giveaways::get_by_id(&mut conn, *id).await?;
90
91 let token = authorize(
92 &mut conn,
93 Act::Edit,
94 Some(user.id),
95 Res::Course(code_giveaway.course_id),
96 )
97 .await?;
98
99 let codes = models::code_giveaway_codes::insert_many(&mut conn, *id, &codes, user.id).await?;
100
101 token.authorized_ok(web::Json(codes))
102}
103
104#[instrument(skip(pool))]
108async fn get_codes_by_code_giveaway_id(
109 pool: web::Data<PgPool>,
110 id: web::Path<Uuid>,
111 user: AuthUser,
112) -> ControllerResult<web::Json<Vec<CodeGiveawayCode>>> {
113 let mut conn = pool.acquire().await?;
114
115 let code_giveaway = models::code_giveaways::get_by_id(&mut conn, *id).await?;
116
117 let token = authorize(
118 &mut conn,
119 Act::Edit,
120 Some(user.id),
121 Res::Course(code_giveaway.course_id),
122 )
123 .await?;
124
125 let codes = models::code_giveaway_codes::get_all_by_code_giveaway_id(&mut conn, *id).await?;
126
127 token.authorized_ok(web::Json(codes))
128}
129
130#[instrument(skip(pool))]
134async fn delete_code_giveaway_code(
135 pool: web::Data<PgPool>,
136 path: web::Path<(Uuid, Uuid)>,
137 user: AuthUser,
138) -> ControllerResult<web::Json<()>> {
139 let (id, code_id) = path.into_inner();
140 let mut conn = pool.acquire().await?;
141
142 let giveaway = models::code_giveaways::get_by_id(&mut conn, id).await?;
143 let code = models::code_giveaway_codes::get_by_id(&mut conn, code_id).await?;
144
145 if id != code.code_giveaway_id {
146 return Err(ControllerError::new(
147 ControllerErrorType::BadRequest,
148 "Code giveaway and code course mismatch",
149 None,
150 ));
151 }
152
153 let token = authorize(
154 &mut conn,
155 Act::Edit,
156 Some(user.id),
157 Res::Course(giveaway.course_id),
158 )
159 .await?;
160
161 models::code_giveaway_codes::delete_by_id(&mut conn, code_id).await?;
162
163 token.authorized_ok(web::Json(()))
164}
165
166#[instrument(skip(pool))]
170async fn get_codes_by_code_giveaway_id_csv(
171 pool: web::Data<PgPool>,
172 id: web::Path<Uuid>,
173 user: AuthUser,
174) -> ControllerResult<HttpResponse> {
175 let mut conn = pool.acquire().await?;
176
177 let code_giveaway = models::code_giveaways::get_by_id(&mut conn, *id).await?;
178 let course = models::courses::get_course(&mut conn, code_giveaway.course_id).await?;
179
180 let token = authorize(
181 &mut conn,
182 Act::Edit,
183 Some(user.id),
184 Res::Course(code_giveaway.course_id),
185 )
186 .await?;
187
188 general_export(
189 pool,
190 &format!(
191 "attachment; filename=\"Giveaway codes {} / {} - {}.csv\"",
192 code_giveaway.name,
193 course.name,
194 Utc::now().format("%Y-%m-%d")
195 ),
196 CodeGiveawayCodesExportOperation {
197 code_giveaway_id: *id,
198 },
199 token,
200 )
201 .await
202}
203
204pub fn _add_routes(cfg: &mut ServiceConfig) {
212 cfg.route(
213 "by-course/{course_id}",
214 web::get().to(get_code_giveaways_by_course),
215 )
216 .route("", web::post().to(create_code_giveaway))
217 .route("{id}", web::get().to(get_code_giveaway_by_id))
218 .route("{id}/codes", web::get().to(get_codes_by_code_giveaway_id))
219 .route(
220 "{id}/codes/csv",
221 web::get().to(get_codes_by_code_giveaway_id_csv),
222 )
223 .route("{id}/codes", web::post().to(add_codes_to_code_giveaway))
224 .route(
225 "{id}/codes/{code_id}",
226 web::delete().to(delete_code_giveaway_code),
227 );
228}