feat: application details structure

This commit is contained in:
Sebastian Pravda 2022-12-05 15:21:30 +01:00
parent 904f8732d6
commit 1262eda871
No known key found for this signature in database
GPG key ID: F3BC84F08EFA3F57
9 changed files with 267 additions and 202 deletions

View file

@ -240,21 +240,25 @@ mod tests {
}
const CANDIDATE_DETAILS: &'static str = "{
\"name\": \"idk\",
\"surname\": \"idk\",
\"birthplace\": \"Praha 1\",
\"birthdate\": \"2015-09-18\",
\"address\": \"Stefanikova jidelna\",
\"telephone\": \"000111222333\",
\"citizenship\": \"Czech Republic\",
\"email\": \"magor@magor.cz\",
\"sex\": \"MALE\",
\"personalIdNumber\": \"0000000000\",
\"study\": \"KB\",
\"parentName\": \"maminka\",
\"parentSurname\": \"chad\",
\"parentTelephone\": \"420111222333\",
\"parentEmail\": \"maminka@centrum.cz\"
\"candidate\": {
\"name\": \"idk\",
\"surname\": \"idk\",
\"birthplace\": \"Praha 1\",
\"birthdate\": \"2015-09-18\",
\"address\": \"Stefanikova jidelna\",
\"telephone\": \"000111222333\",
\"citizenship\": \"Czech Republic\",
\"email\": \"magor@magor.cz\",
\"sex\": \"MALE\",
\"personalIdNumber\": \"0000000000\",
\"study\": \"KB\"
},
\"parent\": {
\"name\": \"maminka\",
\"surname\": \"chad\",
\"telephone\": \"420111222333\",
\"email\": \"maminka@centrum.cz\"
}
}";
#[test]

View file

@ -1,4 +1,4 @@
use crate::{Mutation, models::candidate_details::EncryptedApplicationDetails};
use crate::{Mutation, models::candidate_details::{EncryptedCandidateDetails}};
use ::entity::candidate::{self};
use sea_orm::*;
@ -44,20 +44,20 @@ impl Mutation {
pub async fn add_candidate_details(
db: &DbConn,
user: candidate::Model,
enc_details: EncryptedApplicationDetails,
enc_candidate: EncryptedCandidateDetails,
) -> Result<candidate::Model, sea_orm::DbErr> {
let mut user: candidate::ActiveModel = user.into();
user.name = Set(Some(enc_details.name.into()));
user.surname = Set(Some(enc_details.surname.into()));
user.birthplace = Set(Some(enc_details.birthplace.into()));
user.birthdate = Set(Some(enc_details.birthdate.into()));
user.address = Set(Some(enc_details.address.into()));
user.telephone = Set(Some(enc_details.telephone.into()));
user.citizenship = Set(Some(enc_details.citizenship.into()));
user.email = Set(Some(enc_details.email.into()));
user.sex = Set(Some(enc_details.sex.into()));
user.personal_identification_number = Set(enc_details.personal_id_number.into()); // TODO: do not set this here, it is already set in the create_candidate mutation???
user.study = Set(Some(enc_details.study.into()));
user.name = Set(Some(enc_candidate.name.into()));
user.surname = Set(Some(enc_candidate.surname.into()));
user.birthplace = Set(Some(enc_candidate.birthplace.into()));
user.birthdate = Set(Some(enc_candidate.birthdate.into()));
user.address = Set(Some(enc_candidate.address.into()));
user.telephone = Set(Some(enc_candidate.telephone.into()));
user.citizenship = Set(Some(enc_candidate.citizenship.into()));
user.email = Set(Some(enc_candidate.email.into()));
user.sex = Set(Some(enc_candidate.sex.into()));
user.personal_identification_number = Set(enc_candidate.personal_id_number.into()); // TODO: do not set this here, it is already set in the create_candidate mutation???
user.study = Set(Some(enc_candidate.study.into()));
user.updated_at = Set(chrono::offset::Local::now().naive_local());
@ -117,7 +117,7 @@ mod tests {
vec!["age1u889gp407hsz309wn09kxx9anl6uns30m27lfwnctfyq9tq4qpus8tzmq5".to_string()],
).await.unwrap();
Mutation::add_candidate_details(&db, candidate, encrypted_details).await.unwrap();
Mutation::add_candidate_details(&db, candidate, encrypted_details.candidate).await.unwrap();
let candidate = Query::find_candidate_by_id(&db, APPLICATION_ID)
.await

View file

@ -1,4 +1,4 @@
use crate::{Mutation, models::candidate_details::EncryptedApplicationDetails};
use crate::{Mutation, models::candidate_details::{EncryptedParentDetails}};
use ::entity::parent::{self, Model};
use sea_orm::*;
@ -18,13 +18,13 @@ impl Mutation {
pub async fn add_parent_details(
db: &DbConn,
parent: Model,
enc_details: EncryptedApplicationDetails, // TODO: use seperate struct??
enc_parent: EncryptedParentDetails,
) -> Result<Model, sea_orm::DbErr> {
let mut user: parent::ActiveModel = parent.into();
user.name = Set(Some(enc_details.parent_name.into()));
user.surname = Set(Some(enc_details.parent_surname.into()));
user.telephone = Set(Some(enc_details.parent_telephone.into()));
user.email = Set(Some(enc_details.parent_email.into()));
user.name = Set(Some(enc_parent.name.into()));
user.surname = Set(Some(enc_parent.surname.into()));
user.telephone = Set(Some(enc_parent.telephone.into()));
user.email = Set(Some(enc_parent.email.into()));
user.updated_at = Set(chrono::offset::Local::now().naive_local());
@ -88,7 +88,7 @@ mod tests {
.await
.unwrap();
Mutation::add_parent_details(&db, parent, encrypted_details)
Mutation::add_parent_details(&db, parent, encrypted_details.parent)
.await
.unwrap();

View file

@ -27,11 +27,10 @@ pub struct BaseCandidateResponse {
pub submitted: bool,
}
/// Candidate details (admin and candidate endpoints)
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct ApplicationDetails {
// Candidate
pub struct CandidateDetails {
// pub application_id: i32,
pub name: String,
pub surname: String,
pub birthplace: String,
@ -43,12 +42,49 @@ pub struct ApplicationDetails {
pub sex: String,
pub study: String,
pub personal_id_number: String,
// Parent
pub parent_name: String,
pub parent_surname: String,
pub parent_telephone: String,
pub parent_email: String,
}
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct ParentDetails {
// pub application_id: i32,
pub name: String,
pub surname: String,
pub telephone: String,
pub email: String,
}
/// Candidate details (admin and candidate endpoints)
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct ApplicationDetails {
// Candidate
pub candidate: CandidateDetails,
pub parent: ParentDetails,
// pub opt_parent2: Option<ParentDetails>,
}
/* impl ApplicationDetails {
pub fn new_one_parent(
candidate: CandidateDetails,
parent: ParentDetails,
) -> Self {
Self {
candidate,
parent,
opt_parent2: None,
}
}
pub fn new_two_parents(
candidate: CandidateDetails,
parent: ParentDetails,
opt_parent2: ParentDetails,
) -> Self {
Self {
candidate,
parent,
opt_parent2: Some(opt_parent2),
}
}
} */
/// CSV export (admin endpoint)
#[derive(FromQueryResult, Serialize, Default)]

View file

@ -4,14 +4,15 @@ use entity::{candidate, parent};
use crate::{crypto, models::candidate::{CandidateWithParent, ApplicationDetails}, error::ServiceError};
use super::candidate::{CandidateDetails, ParentDetails};
pub const NAIVE_DATE_FMT: &str = "%Y-%m-%d";
#[derive(Clone)]
pub struct EncryptedString(String);
#[derive(Clone)]
pub struct EncryptedApplicationDetails {
// Candidate
pub struct EncryptedCandidateDetails {
pub name: EncryptedString,
pub surname: EncryptedString,
pub birthplace: EncryptedString,
@ -23,12 +24,19 @@ pub struct EncryptedApplicationDetails {
pub sex: EncryptedString,
pub personal_id_number: EncryptedString,
pub study: String,
}
// Parent
pub parent_name: EncryptedString,
pub parent_surname: EncryptedString,
pub parent_telephone: EncryptedString,
pub parent_email: EncryptedString,
#[derive(Clone)]
pub struct EncryptedParentDetails {
pub name: EncryptedString,
pub surname: EncryptedString,
pub telephone: EncryptedString,
pub email: EncryptedString,
}
#[derive(Clone)]
pub struct EncryptedApplicationDetails {
pub candidate: EncryptedCandidateDetails,
pub parent: EncryptedParentDetails,
}
impl EncryptedString {
@ -91,80 +99,89 @@ impl EncryptedApplicationDetails {
form: &ApplicationDetails,
recipients: Vec<String>,
) -> Result<EncryptedApplicationDetails, ServiceError> {
let birthdate_str = form.birthdate.format(NAIVE_DATE_FMT).to_string();
let birthdate_str = form.candidate.birthdate.format(NAIVE_DATE_FMT).to_string();
let d = tokio::try_join!(
EncryptedString::new(&form.name, &recipients),
EncryptedString::new(&form.surname, &recipients),
EncryptedString::new(&form.birthplace, &recipients),
EncryptedString::new(&form.candidate.name, &recipients),
EncryptedString::new(&form.candidate.surname, &recipients),
EncryptedString::new(&form.candidate.birthplace, &recipients),
EncryptedString::new(&birthdate_str, &recipients),
EncryptedString::new(&form.address, &recipients),
EncryptedString::new(&form.telephone, &recipients),
EncryptedString::new(&form.citizenship, &recipients),
EncryptedString::new(&form.email, &recipients),
EncryptedString::new(&form.sex, &recipients),
EncryptedString::new(&form.personal_id_number, &recipients),
EncryptedString::new(&form.candidate.address, &recipients),
EncryptedString::new(&form.candidate.telephone, &recipients),
EncryptedString::new(&form.candidate.citizenship, &recipients),
EncryptedString::new(&form.candidate.email, &recipients),
EncryptedString::new(&form.candidate.sex, &recipients),
EncryptedString::new(&form.candidate.personal_id_number, &recipients),
EncryptedString::new(&form.parent_name, &recipients),
EncryptedString::new(&form.parent_surname, &recipients),
EncryptedString::new(&form.parent_telephone, &recipients),
EncryptedString::new(&form.parent_email, &recipients),
EncryptedString::new(&form.parent.name, &recipients),
EncryptedString::new(&form.parent.surname, &recipients),
EncryptedString::new(&form.parent.telephone, &recipients),
EncryptedString::new(&form.parent.email, &recipients),
)?;
Ok(EncryptedApplicationDetails {
name: d.0,
surname: d.1,
birthplace: d.2,
birthdate: d.3,
address: d.4,
telephone: d.5,
citizenship: d.6,
email: d.7,
sex: d.8,
personal_id_number: d.9,
study: form.study.clone(),
candidate: EncryptedCandidateDetails {
name: d.0,
surname: d.1,
birthplace: d.2,
birthdate: d.3,
address: d.4,
telephone: d.5,
citizenship: d.6,
email: d.7,
sex: d.8,
personal_id_number: d.9,
study: form.candidate.study.clone(),
},
parent: EncryptedParentDetails {
name: d.10,
surname: d.11,
telephone: d.12,
email: d.13,
}
parent_name: d.10,
parent_surname: d.11,
parent_telephone: d.12,
parent_email: d.13,
})
}
pub async fn decrypt(self, priv_key: String) -> Result<ApplicationDetails, ServiceError> {
let d = tokio::try_join!(
self.name.decrypt(&priv_key), // 0
self.surname.decrypt(&priv_key), // 1
self.birthplace.decrypt(&priv_key), // 2
self.birthdate.decrypt(&priv_key), // 3
self.address.decrypt(&priv_key), // 4
self.telephone.decrypt(&priv_key), // 5
self.citizenship.decrypt(&priv_key), // 6
self.email.decrypt(&priv_key), // 7
self.sex.decrypt(&priv_key), // 8
self.personal_id_number.decrypt(&priv_key),// 9
self.parent_name.decrypt(&priv_key), // 10
self.parent_surname.decrypt(&priv_key), // 11
self.parent_telephone.decrypt(&priv_key), // 12
self.parent_email.decrypt(&priv_key), // 13
self.candidate.name.decrypt(&priv_key), // 0
self.candidate.surname.decrypt(&priv_key), // 1
self.candidate.birthplace.decrypt(&priv_key), // 2
self.candidate.birthdate.decrypt(&priv_key), // 3
self.candidate.address.decrypt(&priv_key), // 4
self.candidate.telephone.decrypt(&priv_key), // 5
self.candidate.citizenship.decrypt(&priv_key), // 6
self.candidate.email.decrypt(&priv_key), // 7
self.candidate.sex.decrypt(&priv_key), // 8
self.candidate.personal_id_number.decrypt(&priv_key),// 9
self.parent.name.decrypt(&priv_key), // 10
self.parent.surname.decrypt(&priv_key), // 11
self.parent.telephone.decrypt(&priv_key), // 12
self.parent.email.decrypt(&priv_key), // 13
)?;
Ok(ApplicationDetails {
name: d.0,
surname: d.1,
birthplace: d.2,
birthdate: NaiveDate::parse_from_str(&d.3, NAIVE_DATE_FMT).unwrap(), // TODO
address: d.4,
telephone: d.5,
citizenship: d.6,
email: d.7,
sex: d.8,
personal_id_number: d.9,
study: self.study,
candidate: CandidateDetails {
name: d.0,
surname: d.1,
birthplace: d.2,
birthdate: NaiveDate::parse_from_str(&d.3, NAIVE_DATE_FMT).unwrap(), // TODO
address: d.4,
telephone: d.5,
citizenship: d.6,
email: d.7,
sex: d.8,
personal_id_number: d.9,
study: self.candidate.study,
},
parent: ParentDetails {
name: d.10,
surname: d.11,
telephone: d.12,
email: d.13,
}
parent_name: d.10,
parent_surname: d.11,
parent_telephone: d.12,
parent_email: d.13,
})
}
}
@ -176,22 +193,26 @@ impl TryFrom<(candidate::Model, parent::Model)> for EncryptedApplicationDetails
(candidate, parent): (candidate::Model, parent::Model),
) -> Result<Self, Self::Error> {
Ok(EncryptedApplicationDetails {
name: EncryptedString::try_from(candidate.name)?,
surname: EncryptedString::try_from(candidate.surname)?,
birthplace: EncryptedString::try_from(candidate.birthplace)?,
birthdate: EncryptedString::try_from(candidate.birthdate)?,
address: EncryptedString::try_from(candidate.address)?,
telephone: EncryptedString::try_from(candidate.telephone)?,
citizenship: EncryptedString::try_from(candidate.citizenship)?,
email: EncryptedString::try_from(candidate.email)?,
sex: EncryptedString::try_from(candidate.sex)?,
personal_id_number: EncryptedString::from(candidate.personal_identification_number),
study: candidate.study.ok_or(ServiceError::CandidateDetailsNotSet)?,
candidate: EncryptedCandidateDetails {
name: EncryptedString::try_from(candidate.name)?,
surname: EncryptedString::try_from(candidate.surname)?,
birthplace: EncryptedString::try_from(candidate.birthplace)?,
birthdate: EncryptedString::try_from(candidate.birthdate)?,
address: EncryptedString::try_from(candidate.address)?,
telephone: EncryptedString::try_from(candidate.telephone)?,
citizenship: EncryptedString::try_from(candidate.citizenship)?,
email: EncryptedString::try_from(candidate.email)?,
sex: EncryptedString::try_from(candidate.sex)?,
personal_id_number: EncryptedString::from(candidate.personal_identification_number),
study: candidate.study.ok_or(ServiceError::CandidateDetailsNotSet)?,
},
parent: EncryptedParentDetails {
name: EncryptedString::try_from(parent.name)?,
surname: EncryptedString::try_from(parent.surname)?,
telephone: EncryptedString::try_from(parent.telephone)?,
email: EncryptedString::try_from(parent.email)?,
}
parent_name: EncryptedString::try_from(parent.name)?,
parent_surname: EncryptedString::try_from(parent.surname)?,
parent_telephone: EncryptedString::try_from(parent.telephone)?,
parent_email: EncryptedString::try_from(parent.email)?,
})
}
}
@ -203,22 +224,26 @@ impl TryFrom<CandidateWithParent> for EncryptedApplicationDetails {
cp: CandidateWithParent,
) -> Result<Self, Self::Error> {
Ok(EncryptedApplicationDetails {
name: EncryptedString::try_from(cp.name)?,
surname: EncryptedString::try_from(cp.surname)?,
birthplace: EncryptedString::try_from(cp.birthplace)?,
birthdate: EncryptedString::try_from(cp.birthdate)?,
address: EncryptedString::try_from(cp.address)?,
telephone: EncryptedString::try_from(cp.telephone)?,
citizenship: EncryptedString::try_from(cp.citizenship)?,
email: EncryptedString::try_from(cp.email)?,
sex: EncryptedString::try_from(cp.sex)?,
personal_id_number: EncryptedString::try_from(cp.personal_identification_number)?,
study: cp.study.ok_or(ServiceError::CandidateDetailsNotSet)?,
candidate: EncryptedCandidateDetails {
name: EncryptedString::try_from(cp.name)?,
surname: EncryptedString::try_from(cp.surname)?,
birthplace: EncryptedString::try_from(cp.birthplace)?,
birthdate: EncryptedString::try_from(cp.birthdate)?,
address: EncryptedString::try_from(cp.address)?,
telephone: EncryptedString::try_from(cp.telephone)?,
citizenship: EncryptedString::try_from(cp.citizenship)?,
email: EncryptedString::try_from(cp.email)?,
sex: EncryptedString::try_from(cp.sex)?,
personal_id_number: EncryptedString::try_from(cp.personal_identification_number)?,
study: cp.study.ok_or(ServiceError::CandidateDetailsNotSet)?,
},
parent: EncryptedParentDetails {
name: EncryptedString::try_from(cp.parent_name)?,
surname: EncryptedString::try_from(cp.parent_surname)?,
telephone: EncryptedString::try_from(cp.parent_telephone)?,
email: EncryptedString::try_from(cp.parent_email)?,
}
parent_name: EncryptedString::try_from(cp.parent_name)?,
parent_surname: EncryptedString::try_from(cp.parent_surname)?,
parent_telephone: EncryptedString::try_from(cp.parent_telephone)?,
parent_email: EncryptedString::try_from(cp.parent_email)?,
})
}
}
@ -240,7 +265,7 @@ pub mod tests {
use once_cell::sync::Lazy;
use crate::crypto;
use crate::{crypto, models::candidate::{CandidateDetails, ParentDetails}};
use super::{ApplicationDetails, EncryptedApplicationDetails, EncryptedString};
@ -249,40 +274,44 @@ pub mod tests {
pub static APPLICATION_DETAILS: Lazy<Mutex<ApplicationDetails>> = Lazy::new(||
Mutex::new(ApplicationDetails {
name: "name".to_string(),
surname: "surname".to_string(),
birthplace: "birthplace".to_string(),
birthdate: chrono::NaiveDate::from_ymd(2000, 1, 1),
address: "address".to_string(),
telephone: "telephone".to_string(),
citizenship: "citizenship".to_string(),
email: "email".to_string(),
sex: "sex".to_string(),
personal_id_number: "personal_id_number".to_string(),
study: "study".to_string(),
parent_email: "parent_email".to_string(),
parent_name: "parent_name".to_string(),
parent_surname: "parent_surname".to_string(),
parent_telephone: "parent_telephone".to_string()
candidate: CandidateDetails {
name: "name".to_string(),
surname: "surname".to_string(),
birthplace: "birthplace".to_string(),
birthdate: chrono::NaiveDate::from_ymd(2000, 1, 1),
address: "address".to_string(),
telephone: "telephone".to_string(),
citizenship: "citizenship".to_string(),
email: "email".to_string(),
sex: "sex".to_string(),
personal_id_number: "personal_id_number".to_string(),
study: "study".to_string(),
},
parent: ParentDetails {
email: "parent_email".to_string(),
name: "parent_name".to_string(),
surname: "parent_surname".to_string(),
telephone: "parent_telephone".to_string()
}
})
);
pub fn assert_all_application_details(details: &ApplicationDetails) {
assert_eq!(details.name, "name");
assert_eq!(details.surname, "surname");
assert_eq!(details.birthplace, "birthplace");
assert_eq!(details.birthdate, chrono::NaiveDate::from_ymd(2000, 1, 1));
assert_eq!(details.address, "address");
assert_eq!(details.telephone, "telephone");
assert_eq!(details.citizenship, "citizenship");
assert_eq!(details.email, "email");
assert_eq!(details.sex, "sex");
assert_eq!(details.study, "study");
assert_eq!(details.personal_id_number, "personal_id_number");
assert_eq!(details.parent_name, "parent_name");
assert_eq!(details.parent_surname, "parent_surname");
assert_eq!(details.parent_telephone, "parent_telephone");
assert_eq!(details.parent_email, "parent_email");
assert_eq!(details.candidate.name, "name");
assert_eq!(details.candidate.surname, "surname");
assert_eq!(details.candidate.birthplace, "birthplace");
assert_eq!(details.candidate.birthdate, chrono::NaiveDate::from_ymd(2000, 1, 1));
assert_eq!(details.candidate.address, "address");
assert_eq!(details.candidate.telephone, "telephone");
assert_eq!(details.candidate.citizenship, "citizenship");
assert_eq!(details.candidate.email, "email");
assert_eq!(details.candidate.sex, "sex");
assert_eq!(details.candidate.study, "study");
assert_eq!(details.candidate.personal_id_number, "personal_id_number");
assert_eq!(details.parent.name, "parent_name");
assert_eq!(details.parent.surname, "parent_surname");
assert_eq!(details.parent.telephone, "parent_telephone");
assert_eq!(details.parent.email, "parent_email");
}
#[tokio::test]
@ -295,19 +324,19 @@ pub mod tests {
.unwrap();
assert_eq!(
crypto::decrypt_password_with_private_key(&encrypted_details.name.0, PRIVATE_KEY)
crypto::decrypt_password_with_private_key(&encrypted_details.candidate.name.0, PRIVATE_KEY)
.await
.unwrap(),
"name"
);
assert_eq!(
crypto::decrypt_password_with_private_key(&encrypted_details.email.0, PRIVATE_KEY)
crypto::decrypt_password_with_private_key(&encrypted_details.candidate.email.0, PRIVATE_KEY)
.await
.unwrap(),
"email"
);
assert_eq!(
crypto::decrypt_password_with_private_key(&encrypted_details.sex.0, PRIVATE_KEY)
crypto::decrypt_password_with_private_key(&encrypted_details.candidate.sex.0, PRIVATE_KEY)
.await
.unwrap(),
"sex"

View file

@ -14,13 +14,7 @@ impl ApplicationService {
plain_text_password: &String,
personal_id_number: String,
) -> Result<(candidate::Model, parent::Model), ServiceError> {
Ok(
/* tokio::try_join!( // TODO: try_join! is not working
CandidateService::create(db, application_id, plain_text_password, personal_id_number),
ParentService::create(db, application_id)
)? */
Ok(
(
CandidateService::create(db, application_id, plain_text_password, personal_id_number).await?,
ParentService::create(db, application_id).await?
@ -47,8 +41,8 @@ impl ApplicationService {
Ok(
tokio::try_join!(
CandidateService::add_candidate_details(db, candidate, enc_details.clone()),
ParentService::add_parent_details(db, parent, enc_details.clone())
CandidateService::add_candidate_details(db, candidate, enc_details.candidate),
ParentService::add_parent_details(db, parent, enc_details.parent)
)?
)
}

View file

@ -2,7 +2,7 @@ use entity::candidate;
use sea_orm::{prelude::Uuid, DbConn};
use crate::{
models::candidate_details::{EncryptedApplicationDetails, EncryptedString},
models::candidate_details::{EncryptedApplicationDetails, EncryptedString, EncryptedCandidateDetails},
crypto::{self, hash_password},
error::ServiceError,
Mutation, Query, models::candidate::{BaseCandidateResponse, CreateCandidateResponse}, utils::db::get_recipients,
@ -150,9 +150,9 @@ impl CandidateService {
pub(in crate::services) async fn add_candidate_details(
db: &DbConn,
candidate: candidate::Model,
enc_details: EncryptedApplicationDetails,
enc_details: EncryptedCandidateDetails,
) -> Result<entity::candidate::Model, ServiceError> {
let model = Mutation::add_candidate_details(db, candidate, enc_details.clone()).await?;
let model = Mutation::add_candidate_details(db, candidate, enc_details).await?;
Ok(model)
}

View file

@ -1,7 +1,7 @@
use entity::{parent};
use sea_orm::DbConn;
use crate::{error::ServiceError, Mutation, models::candidate_details::EncryptedApplicationDetails};
use crate::{error::ServiceError, Mutation, models::candidate_details::{EncryptedParentDetails}};
pub struct ParentService;
@ -19,7 +19,7 @@ impl ParentService {
pub async fn add_parent_details(
db: &DbConn,
parent: parent::Model,
enc_details: EncryptedApplicationDetails,
enc_details: EncryptedParentDetails,
) -> Result<parent::Model, ServiceError> {
let parent = Mutation::add_parent_details(db, parent, enc_details)
.await?;

View file

@ -6,24 +6,26 @@ type Row = CandidateWithParent;
impl From<(i32, ApplicationDetails)> for Row {
fn from((application, d): (i32, ApplicationDetails)) -> Self {
let c = d.candidate;
let p = d.parent;
Self {
application,
name: Some(d.name),
surname: Some(d.surname),
birthplace: Some(d.birthplace),
birthdate: Some(d.birthdate.to_string()),
address: Some(d.address),
telephone: Some(d.telephone),
citizenship: Some(d.citizenship),
email: Some(d.email),
sex: Some(d.sex),
study: Some(d.study),
personal_identification_number: Some(d.personal_id_number),
name: Some(c.name),
surname: Some(c.surname),
birthplace: Some(c.birthplace),
birthdate: Some(c.birthdate.to_string()),
address: Some(c.address),
telephone: Some(c.telephone),
citizenship: Some(c.citizenship),
email: Some(c.email),
sex: Some(c.sex),
study: Some(c.study),
personal_identification_number: Some(c.personal_id_number),
parent_name: Some(d.parent_name),
parent_surname: Some(d.parent_surname),
parent_telephone: Some(d.parent_telephone),
parent_email: Some(d.parent_email),
parent_name: Some(p.name),
parent_surname: Some(p.surname),
parent_telephone: Some(p.telephone),
parent_email: Some(p.email),
}
}
}