1use actix_web::web::Query;
4use actix_web::{
5 delete, get, patch, post, put,
6 web::{Json, Path},
7 HttpResponse, Result,
8};
9use uuid::Uuid;
10
11use crate::service::map_access_control::check_creation_permission;
12use crate::{
13 config::{
14 auth::user_info::UserInfo,
15 data::{SharedBroadcaster, SharedPool},
16 },
17 model::dto::{
18 actions::{Action, ActionType, UpdatePlantingAdditionalNamePayload},
19 ArchiveSeedDto, NewSeedDto, PageParameters, SeedSearchParameters,
20 },
21 service,
22};
23
24#[utoipa::path(
34 context_path = "/api/seeds",
35 params(
36 SeedSearchParameters,
37 PageParameters
38 ),
39 responses(
40 (status = 200, description = "Fetch all seeds", body = PageSeedDto)
41 ),
42 security(
43 ("oauth2" = [])
44 )
45)]
46#[get("")]
47pub async fn find(
48 search_query: Query<SeedSearchParameters>,
49 page_query: Query<PageParameters>,
50 user_info: UserInfo,
51 pool: SharedPool,
52) -> Result<HttpResponse> {
53 let response = service::seed::find(
54 search_query.into_inner(),
55 page_query.into_inner(),
56 user_info.id,
57 &pool,
58 )
59 .await?;
60 Ok(HttpResponse::Ok().json(response))
61}
62
63#[utoipa::path(
68 context_path = "/api/seeds",
69 responses(
70 (status = 200, description = "Fetch seed by id", body = SeedDto)
71 ),
72 security(
73 ("oauth2" = [])
74 )
75)]
76#[get("/{id}")]
77pub async fn find_by_id(
78 id: Path<i32>,
79 user_info: UserInfo,
80 pool: SharedPool,
81) -> Result<HttpResponse> {
82 let response = service::seed::find_by_id((*id).into(), user_info.id, &pool).await?;
83 Ok(HttpResponse::Ok().json(response))
84}
85
86#[utoipa::path(
91 context_path = "/api/seeds",
92 request_body = NewSeedDto,
93 responses(
94 (status = 201, description = "Create a seed", body = SeedDto)
95 ),
96 security(
97 ("oauth2" = [])
98 )
99)]
100#[post("")]
101pub async fn create(
102 new_seed_json: Json<NewSeedDto>,
103 user_info: UserInfo,
104 pool: SharedPool,
105) -> Result<HttpResponse> {
106 check_creation_permission(&user_info).await?;
107 let response = service::seed::create(new_seed_json.0, user_info.id, &pool).await?;
108 Ok(HttpResponse::Created().json(response))
109}
110
111#[utoipa::path(
116 context_path = "/api/seeds",
117 responses(
118 (status = 200, description = "Delete a seed", body = String)
119 ),
120 security(
121 ("oauth2" = [])
122 )
123)]
124#[delete("/{id}")]
125pub async fn delete_by_id(
126 path: Path<i32>,
127 user_info: UserInfo,
128 pool: SharedPool,
129) -> Result<HttpResponse> {
130 service::seed::delete_by_id((*path).into(), user_info.id, &pool).await?;
131 Ok(HttpResponse::Ok().json(""))
132}
133
134#[put("/{id}")]
139pub async fn edit_by_id(
140 id: Path<i32>,
141 edit_seed_json: Json<NewSeedDto>,
142 user_info: UserInfo,
143 pool: SharedPool,
144 broadcaster: SharedBroadcaster,
145) -> Result<HttpResponse> {
146 let response = service::seed::edit((*id).into(), user_info.id, edit_seed_json.0, &pool).await?;
147 let affected_plantings = service::plantings::find_by_seed_id((*id).into(), &pool);
148
149 for planting in affected_plantings.await? {
150 broadcaster
151 .broadcast_all_maps(Action {
152 action_id: Uuid::now_v7(),
153 user_id: user_info.id,
154 action: ActionType::UpdatePlantingAdditionalName(
155 UpdatePlantingAdditionalNamePayload::new(
156 &planting,
157 Some(response.name.clone()),
158 ),
159 ),
160 })
161 .await;
162 }
163
164 Ok(HttpResponse::Accepted().json(response))
165}
166
167#[patch("/{id}/archive")]
173pub async fn archive(
174 id: Path<i32>,
175 archive_seed_json: Json<ArchiveSeedDto>,
176 user_info: UserInfo,
177 pool: SharedPool,
178) -> Result<HttpResponse> {
179 let response =
180 service::seed::archive((*id).into(), user_info.id, archive_seed_json.0, &pool).await?;
181 Ok(HttpResponse::Accepted().json(response))
182}