mirror of
https://github.com/danbulant/Portfolio
synced 2026-07-07 12:00:43 +00:00
feat: lock candidate delete if candidate already filled application form
This commit is contained in:
parent
0a3ce57b09
commit
c00d207f61
2 changed files with 23 additions and 12 deletions
|
|
@ -2,7 +2,7 @@ use std::net::{SocketAddr, IpAddr, Ipv4Addr};
|
||||||
|
|
||||||
use portfolio_core::{
|
use portfolio_core::{
|
||||||
crypto::random_12_char_string,
|
crypto::random_12_char_string,
|
||||||
services::{admin_service::AdminService, candidate_service::CandidateService, application_service::ApplicationService, portfolio_service::PortfolioService}, models::{candidate::{CreateCandidateResponse, ApplicationDetails}, auth::AuthenticableTrait, application::ApplicationResponse}, sea_orm::prelude::Uuid, Query, error::ServiceError, utils::csv,
|
services::{admin_service::AdminService, application_service::ApplicationService, portfolio_service::PortfolioService}, models::{candidate::{CreateCandidateResponse, ApplicationDetails}, auth::AuthenticableTrait, application::ApplicationResponse}, sea_orm::prelude::Uuid, Query, error::ServiceError, utils::csv,
|
||||||
};
|
};
|
||||||
use requests::{AdminLoginRequest, RegisterRequest};
|
use requests::{AdminLoginRequest, RegisterRequest};
|
||||||
use rocket::http::{Cookie, Status, CookieJar};
|
use rocket::http::{Cookie, Status, CookieJar};
|
||||||
|
|
@ -189,18 +189,12 @@ pub async fn delete_candidate(
|
||||||
.await
|
.await
|
||||||
.map_err(|e| to_custom_error(ServiceError::DbError(e)))?
|
.map_err(|e| to_custom_error(ServiceError::DbError(e)))?
|
||||||
.ok_or(to_custom_error(ServiceError::CandidateNotFound))?;
|
.ok_or(to_custom_error(ServiceError::CandidateNotFound))?;
|
||||||
let candidate = ApplicationService::find_related_candidate(db, &application).await.map_err(to_custom_error)?;
|
|
||||||
|
|
||||||
ApplicationService::delete(db, application).await.map_err(to_custom_error)?;
|
|
||||||
|
|
||||||
let remaining_applications = Query::find_applications_by_candidate_id(db, candidate.id).await
|
ApplicationService::delete(db, application)
|
||||||
.map_err(|e| to_custom_error(ServiceError::DbError(e)))?;
|
.await
|
||||||
|
.map_err(to_custom_error)
|
||||||
|
|
||||||
if remaining_applications.is_empty() {
|
|
||||||
CandidateService::delete_candidate(db, candidate).await.map_err(to_custom_error)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/candidate/<id>/reset_password")]
|
#[post("/candidate/<id>/reset_password")]
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,12 @@
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use chrono::Duration;
|
use chrono::Duration;
|
||||||
use entity::{candidate, parent, application, session};
|
use entity::{candidate, parent, application, session};
|
||||||
|
use log::warn;
|
||||||
use sea_orm::{DbConn, prelude::Uuid, IntoActiveModel};
|
use sea_orm::{DbConn, prelude::Uuid, IntoActiveModel};
|
||||||
|
|
||||||
use crate::{error::ServiceError, Query, utils::db::get_recipients, models::candidate_details::EncryptedApplicationDetails, models::{candidate::{ApplicationDetails, CreateCandidateResponse}, candidate_details::EncryptedString, auth::AuthenticableTrait, application::ApplicationResponse}, Mutation, crypto::{hash_password, self}};
|
use crate::{error::ServiceError, Query, utils::db::get_recipients, models::candidate_details::EncryptedApplicationDetails, models::{candidate::{ApplicationDetails, CreateCandidateResponse}, candidate_details::{EncryptedString, EncryptedCandidateDetails}, auth::AuthenticableTrait, application::ApplicationResponse}, Mutation, crypto::{hash_password, self}};
|
||||||
|
|
||||||
use super::{parent_service::ParentService, candidate_service::CandidateService, session_service::SessionService};
|
use super::{parent_service::ParentService, candidate_service::CandidateService, session_service::SessionService, portfolio_service::PortfolioService};
|
||||||
|
|
||||||
const FIELD_OF_STUDY_PREFIXES: [&str; 3] = ["101", "102", "103"];
|
const FIELD_OF_STUDY_PREFIXES: [&str; 3] = ["101", "102", "103"];
|
||||||
|
|
||||||
|
|
@ -165,7 +166,23 @@ impl ApplicationService {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete(db: &DbConn, application: application::Model) -> Result<(), ServiceError> {
|
pub async fn delete(db: &DbConn, application: application::Model) -> Result<(), ServiceError> {
|
||||||
|
let candidate = ApplicationService::find_related_candidate(db, &application).await?;
|
||||||
|
|
||||||
|
let applications = Query::find_applications_by_candidate_id(db, candidate.id).await?;
|
||||||
|
if applications.len() <= 1 &&
|
||||||
|
(EncryptedCandidateDetails::from(&candidate).is_filled() ||
|
||||||
|
PortfolioService::get_submission_progress(candidate.id).await?.index() > 1) {
|
||||||
|
warn!("FAILED TO DELETE APPLICATION {} (CANDIDATE {}) - LOCKED", application.id, candidate.id);
|
||||||
|
return Err(ServiceError::Forbidden);
|
||||||
|
}
|
||||||
|
|
||||||
Mutation::delete_application(db, application).await?;
|
Mutation::delete_application(db, application).await?;
|
||||||
|
|
||||||
|
let remaining_applications = Query::find_applications_by_candidate_id(db, candidate.id).await?;
|
||||||
|
if remaining_applications.is_empty() {
|
||||||
|
CandidateService::delete_candidate(db, candidate).await?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue