100 lines
3.4 KiB
Rust
100 lines
3.4 KiB
Rust
|
use crate::controllers::members_controller::RequestDate;
|
||
|
use crate::controllers::HttpResult;
|
||
|
use crate::extractors::family_extractor::FamilyInPath;
|
||
|
use crate::models::{Couple, CoupleState, MemberID};
|
||
|
use crate::services::{couples_service, members_service};
|
||
|
use actix_web::{web, HttpResponse};
|
||
|
|
||
|
serde_with::with_prefix!(prefix_wedding "wedding_");
|
||
|
serde_with::with_prefix!(prefix_divorce "divorce_");
|
||
|
|
||
|
#[derive(thiserror::Error, Debug)]
|
||
|
enum CoupleControllerErr {
|
||
|
#[error("Wife and husband are identical!")]
|
||
|
IdenticalWifeHusband,
|
||
|
#[error("Wife does not exist!")]
|
||
|
WifeNotExisting,
|
||
|
#[error("Husband does not exist!")]
|
||
|
HusbandNotExisting,
|
||
|
#[error("Invalid date of wedding")]
|
||
|
MalformedDateOfWedding,
|
||
|
#[error("Invalid date of divorce")]
|
||
|
MalformedDateOfDivorce,
|
||
|
}
|
||
|
|
||
|
#[derive(serde::Deserialize)]
|
||
|
pub struct CoupleRequest {
|
||
|
wife: Option<MemberID>,
|
||
|
husband: Option<MemberID>,
|
||
|
state: Option<CoupleState>,
|
||
|
#[serde(flatten, with = "prefix_wedding")]
|
||
|
wedding: Option<RequestDate>,
|
||
|
#[serde(flatten, with = "prefix_divorce")]
|
||
|
divorce: Option<RequestDate>,
|
||
|
}
|
||
|
|
||
|
impl CoupleRequest {
|
||
|
pub async fn to_couple(self, couple: &mut Couple) -> anyhow::Result<()> {
|
||
|
if let Some(wife) = self.wife {
|
||
|
if !members_service::exists(couple.family_id(), wife).await? {
|
||
|
return Err(CoupleControllerErr::WifeNotExisting.into());
|
||
|
}
|
||
|
|
||
|
if self.wife == self.husband {
|
||
|
return Err(CoupleControllerErr::IdenticalWifeHusband.into());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if let Some(husband) = self.husband {
|
||
|
if !members_service::exists(couple.family_id(), husband).await? {
|
||
|
return Err(CoupleControllerErr::HusbandNotExisting.into());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if let Some(d) = &self.wedding {
|
||
|
if !d.check() {
|
||
|
return Err(CoupleControllerErr::MalformedDateOfWedding.into());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if let Some(d) = &self.divorce {
|
||
|
if !d.check() {
|
||
|
return Err(CoupleControllerErr::MalformedDateOfDivorce.into());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
couple.set_wife(self.wife);
|
||
|
couple.set_husband(self.husband);
|
||
|
couple.set_state(self.state);
|
||
|
|
||
|
couple.wedding_year = self.wedding.as_ref().map(|m| m.year).unwrap_or_default();
|
||
|
couple.wedding_month = self.wedding.as_ref().map(|m| m.month).unwrap_or_default();
|
||
|
couple.wedding_day = self.wedding.as_ref().map(|m| m.day).unwrap_or_default();
|
||
|
|
||
|
couple.divorce_year = self.divorce.as_ref().map(|m| m.year).unwrap_or_default();
|
||
|
couple.divorce_month = self.divorce.as_ref().map(|m| m.month).unwrap_or_default();
|
||
|
couple.divorce_day = self.divorce.as_ref().map(|m| m.day).unwrap_or_default();
|
||
|
|
||
|
Ok(())
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// Create a new couple
|
||
|
pub async fn create(m: FamilyInPath, req: web::Json<CoupleRequest>) -> HttpResult {
|
||
|
let mut couple = couples_service::create(m.family_id()).await?;
|
||
|
|
||
|
if let Err(e) = req.0.to_couple(&mut couple).await {
|
||
|
log::error!("Failed to apply couple information! {e}");
|
||
|
couples_service::delete(&mut couple).await?;
|
||
|
return Ok(HttpResponse::BadRequest().body(e.to_string()));
|
||
|
}
|
||
|
|
||
|
if let Err(e) = couples_service::update(&mut couple).await {
|
||
|
log::error!("Failed to update couple information! {e}");
|
||
|
couples_service::delete(&mut couple).await?;
|
||
|
return Ok(HttpResponse::InternalServerError().finish());
|
||
|
}
|
||
|
|
||
|
Ok(HttpResponse::Ok().json(couple))
|
||
|
}
|