From 41dd84b22d7e82ddcba66b3a5fcc8461c5c8b527 Mon Sep 17 00:00:00 2001 From: Sebastian Pravda Date: Thu, 22 Dec 2022 16:40:24 +0100 Subject: [PATCH 1/2] feat: return more data in candidate list --- api/src/routes/admin.rs | 2 +- core/src/database/query/candidate.rs | 16 +++++-------- core/src/models/candidate.rs | 21 +++++++++-------- core/src/services/candidate_service.rs | 32 +++++++++++--------------- 4 files changed, 32 insertions(+), 39 deletions(-) diff --git a/api/src/routes/admin.rs b/api/src/routes/admin.rs index 4224fa1..7791c7a 100644 --- a/api/src/routes/admin.rs +++ b/api/src/routes/admin.rs @@ -129,7 +129,7 @@ pub async fn list_candidates( } - let candidates = CandidateService::list_candidates(private_key, db, field, page) + let candidates = CandidateService::list_candidates(&private_key, db, field, page) .await .map_err(to_custom_error)?; diff --git a/core/src/database/query/candidate.rs b/core/src/database/query/candidate.rs index 3077dfb..9268b40 100644 --- a/core/src/database/query/candidate.rs +++ b/core/src/database/query/candidate.rs @@ -17,16 +17,15 @@ impl ApplicationId { } } -#[derive(FromQueryResult)] -pub struct CandidateParentResult { +#[derive(FromQueryResult, Clone)] +pub struct CandidateResult { pub application: i32, pub name: Option, pub surname: Option, + pub email: Option, + pub telephone: Option, pub study: Option, pub citizenship: Option, - - pub parent_name: Option, - pub parent_surname: Option, } impl Query { @@ -43,7 +42,7 @@ impl Query { db: &DbConn, field_of_study_opt: Option, page: Option, - ) -> Result, DbErr> { + ) -> Result, DbErr> { let select = Candidate::find(); let query = if let Some(study) = field_of_study_opt { select.filter(candidate::Column::Study.eq(study)) @@ -51,10 +50,7 @@ impl Query { select } .order_by(candidate::Column::Application, Order::Asc) - .join(JoinType::InnerJoin, candidate::Relation::Parent.def()) - .column_as(parent::Column::Name, "parent_name") - .column_as(parent::Column::Surname, "parent_surname") - .into_model::() + .into_model::() .paginate(db, PAGE_SIZE); if let Some(page) = page { diff --git a/core/src/models/candidate.rs b/core/src/models/candidate.rs index 3df8967..70cdf86 100644 --- a/core/src/models/candidate.rs +++ b/core/src/models/candidate.rs @@ -2,7 +2,7 @@ use chrono::NaiveDate; use sea_orm::FromQueryResult; use serde::{Serialize, Deserialize}; -use crate::{error::ServiceError}; +use crate::{error::ServiceError, database::query::candidate::CandidateResult}; use super::candidate_details::decrypt_if_exists; @@ -23,6 +23,8 @@ pub struct BaseCandidateResponse { pub application_id: i32, pub name: String, pub surname: String, + pub email: String, + pub telephone: String, pub study: String, pub submitted: bool, } @@ -91,20 +93,21 @@ pub struct Row { impl BaseCandidateResponse { pub async fn from_encrypted( private_key: &String, - application_id: i32, - name_opt: Option, - surname_opt: Option, - study_opt: Option, + c: CandidateResult, submitted: bool, ) -> Result { - let name = decrypt_if_exists(private_key, name_opt).await?; - let surname = decrypt_if_exists(private_key, surname_opt).await?; + let name = decrypt_if_exists(private_key, c.name).await?; + let surname = decrypt_if_exists(private_key, c.surname).await?; + let email = decrypt_if_exists(private_key, c.email).await?; + let telephone = decrypt_if_exists(private_key, c.telephone).await?; Ok( Self { + application_id: c.application, name, - application_id, surname, - study: study_opt.unwrap_or("".to_string()), + email, + telephone, + study: c.study.unwrap_or("".to_string()), submitted, } ) diff --git a/core/src/services/candidate_service.rs b/core/src/services/candidate_service.rs index b1f0bab..93f2182 100644 --- a/core/src/services/candidate_service.rs +++ b/core/src/services/candidate_service.rs @@ -161,7 +161,7 @@ impl CandidateService { } pub async fn list_candidates( - private_key: String, + private_key: &String, db: &DbConn, field_of_study: Option, page: Option, @@ -173,22 +173,16 @@ impl CandidateService { page ).await?; - let mut result: Vec = vec![]; - - for candidate in candidates { - result.push( - BaseCandidateResponse::from_encrypted( - &private_key, - candidate.application, - candidate.name, - candidate.surname, - candidate.study, - true - ).await? - ) - } - - Ok(result) + futures::future::try_join_all( + candidates + .iter() + .map(|c| async move { + BaseCandidateResponse::from_encrypted( + private_key, + c.clone(), + true).await + }) + ).await } pub fn is_candidate_info(candidate: &candidate::Model) -> bool { @@ -372,12 +366,12 @@ pub mod tests { let db = get_memory_sqlite_connection().await; let admin = create_admin(&db).await; let private_key = crypto::decrypt_password(admin.private_key, "admin".to_string()).await.unwrap(); - let candidates = CandidateService::list_candidates(private_key.clone(), &db, None, None).await.unwrap(); + let candidates = CandidateService::list_candidates(&private_key, &db, None, None).await.unwrap(); assert_eq!(candidates.len(), 0); put_user_data(&db).await; - let candidates = CandidateService::list_candidates(private_key.clone(), &db, None, None).await.unwrap(); + let candidates = CandidateService::list_candidates(&private_key, &db, None, None).await.unwrap(); assert_eq!(candidates.len(), 1); } From b1eb81d00bacf8a5b6eda9c82bbe132b96fae801 Mon Sep 17 00:00:00 2001 From: Sebastian Pravda Date: Thu, 22 Dec 2022 18:51:32 +0100 Subject: [PATCH 2/2] feat(candidate list): get submission progress, fix paging --- core/src/database/query/candidate.rs | 10 ++++++---- core/src/models/candidate.rs | 9 +++++---- core/src/services/candidate_service.rs | 7 ++++--- core/src/services/portfolio_service.rs | 3 ++- 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/core/src/database/query/candidate.rs b/core/src/database/query/candidate.rs index 9268b40..9ff39ee 100644 --- a/core/src/database/query/candidate.rs +++ b/core/src/database/query/candidate.rs @@ -50,13 +50,15 @@ impl Query { select } .order_by(candidate::Column::Application, Order::Asc) - .into_model::() - .paginate(db, PAGE_SIZE); + .into_model::(); if let Some(page) = page { - query.fetch_page(page).await + query + .paginate(db, PAGE_SIZE) + .fetch_page(page).await } else { - query.fetch().await + query + .all(db).await } } diff --git a/core/src/models/candidate.rs b/core/src/models/candidate.rs index 70cdf86..c875763 100644 --- a/core/src/models/candidate.rs +++ b/core/src/models/candidate.rs @@ -2,7 +2,7 @@ use chrono::NaiveDate; use sea_orm::FromQueryResult; use serde::{Serialize, Deserialize}; -use crate::{error::ServiceError, database::query::candidate::CandidateResult}; +use crate::{error::ServiceError, database::query::candidate::CandidateResult, services::portfolio_service::SubmissionProgress}; use super::candidate_details::decrypt_if_exists; @@ -26,7 +26,7 @@ pub struct BaseCandidateResponse { pub email: String, pub telephone: String, pub study: String, - pub submitted: bool, + pub progress: SubmissionProgress, } #[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)] @@ -94,12 +94,13 @@ impl BaseCandidateResponse { pub async fn from_encrypted( private_key: &String, c: CandidateResult, - submitted: bool, + progress: Option, ) -> Result { let name = decrypt_if_exists(private_key, c.name).await?; let surname = decrypt_if_exists(private_key, c.surname).await?; let email = decrypt_if_exists(private_key, c.email).await?; let telephone = decrypt_if_exists(private_key, c.telephone).await?; + let progress = progress.unwrap_or(SubmissionProgress::NoneInCache); Ok( Self { application_id: c.application, @@ -108,7 +109,7 @@ impl BaseCandidateResponse { email, telephone, study: c.study.unwrap_or("".to_string()), - submitted, + progress, } ) } diff --git a/core/src/services/candidate_service.rs b/core/src/services/candidate_service.rs index 93f2182..60b1292 100644 --- a/core/src/services/candidate_service.rs +++ b/core/src/services/candidate_service.rs @@ -178,9 +178,10 @@ impl CandidateService { .iter() .map(|c| async move { BaseCandidateResponse::from_encrypted( - private_key, - c.clone(), - true).await + private_key, + c.clone(), + PortfolioService::get_submission_progress(c.application).await.ok() + ).await }) ).await } diff --git a/core/src/services/portfolio_service.rs b/core/src/services/portfolio_service.rs index 58ce4f2..f43714b 100644 --- a/core/src/services/portfolio_service.rs +++ b/core/src/services/portfolio_service.rs @@ -8,6 +8,7 @@ use tokio::io::{AsyncReadExt, AsyncWriteExt}; use crate::{error::ServiceError, Query, crypto}; +#[derive(Debug)] pub enum SubmissionProgress { NoneInCache, SomeInCache(Vec), @@ -49,7 +50,7 @@ impl Serialize for SubmissionProgress { } -#[derive(Copy, Clone)] +#[derive(Debug, Copy, Clone)] pub enum FileType { CoverLetterPdf = 1, PortfolioLetterPdf = 2,