Add an accommodations reservations module #188

Merged
pierre merged 81 commits from accomodation_module into master 2024-06-22 21:30:26 +00:00
5 changed files with 99 additions and 9 deletions
Showing only changes of commit 18582fdff7 - Show all commits

View File

@ -1,9 +1,9 @@
use crate::constants::StaticConstraints; use crate::constants::StaticConstraints;
use crate::controllers::HttpResult; use crate::controllers::HttpResult;
use crate::extractors::accommodation_extractor::FamilyAndAccommodationInPath;
use crate::extractors::family_extractor::FamilyInPathWithAdminMembership; use crate::extractors::family_extractor::FamilyInPathWithAdminMembership;
use crate::models::{Accommodation, FamilyID}; use crate::models::Accommodation;
use crate::services::accommodations_list_service; use crate::services::accommodations_list_service;
use crate::services::couples_service::{delete, get_all_of_family};
use actix_web::{web, HttpResponse}; use actix_web::{web, HttpResponse};
#[derive(thiserror::Error, Debug)] #[derive(thiserror::Error, Debug)]
@ -66,10 +66,8 @@ pub async fn create(
Ok(HttpResponse::Ok().json(accommodation)) Ok(HttpResponse::Ok().json(accommodation))
} }
/// Delete all the accommodations of a family /// Delete an accommodation
pub async fn delete_all_family(family_id: FamilyID) -> anyhow::Result<()> { pub async fn delete(m: FamilyAndAccommodationInPath) -> HttpResult {
for mut m in get_all_of_family(family_id).await? { accommodations_list_service::delete(&mut m.to_accommodation()).await?;
delete(&mut m).await?; Ok(HttpResponse::Ok().finish())
}
Ok(())
} }

View File

@ -0,0 +1,83 @@
use crate::extractors::family_extractor::FamilyInPath;
use crate::models::{Accommodation, AccommodationID, FamilyID, Membership};
use crate::services::accommodations_list_service;
use actix_web::dev::Payload;
use actix_web::{FromRequest, HttpRequest};
use serde::Deserialize;
use std::ops::Deref;
#[derive(thiserror::Error, Debug)]
enum AccommodationExtractorErr {
#[error("Accommodation {0:?} does not belong to family {1:?}!")]
AccommodationNotInFamily(AccommodationID, FamilyID),
}
#[derive(Debug)]
pub struct FamilyAndAccommodationInPath(Membership, Accommodation);
impl FamilyAndAccommodationInPath {
async fn load_accommodation_from_path(
family: FamilyInPath,
accommodation_id: AccommodationID,
) -> anyhow::Result<Self> {
let accommodation = accommodations_list_service::get_by_id(accommodation_id).await?;
if accommodation.family_id() != family.family_id() {
return Err(AccommodationExtractorErr::AccommodationNotInFamily(
accommodation.id(),
family.family_id(),
)
.into());
}
Ok(Self(family.into(), accommodation))
}
}
impl Deref for FamilyAndAccommodationInPath {
type Target = Accommodation;
fn deref(&self) -> &Self::Target {
&self.1
}
}
impl FamilyAndAccommodationInPath {
pub fn membership(&self) -> &Membership {
&self.0
}
pub fn to_accommodation(self) -> Accommodation {
self.1
}
}
#[derive(Deserialize)]
struct AccommodationIDInPath {
accommodation_id: AccommodationID,
}
impl FromRequest for FamilyAndAccommodationInPath {
type Error = actix_web::Error;
type Future = futures_util::future::LocalBoxFuture<'static, Result<Self, Self::Error>>;
fn from_request(req: &HttpRequest, _payload: &mut Payload) -> Self::Future {
let req = req.clone();
Box::pin(async move {
let family = FamilyInPath::extract(&req).await?;
let accommodation_id = actix_web::web::Path::<AccommodationIDInPath>::from_request(
&req,
&mut Payload::None,
)
.await?
.accommodation_id;
FamilyAndAccommodationInPath::load_accommodation_from_path(family, accommodation_id)
.await
.map_err(|e| {
log::error!("Failed to extract accommodation ID from URL! {}", e);
actix_web::error::ErrorNotFound("Could not fetch accommodation information!")
})
})
}
}

View File

@ -1,3 +1,4 @@
pub mod accommodation_extractor;
pub mod couple_extractor; pub mod couple_extractor;
pub mod family_extractor; pub mod family_extractor;
pub mod member_extractor; pub mod member_extractor;

View File

@ -211,8 +211,12 @@ async fn main() -> std::io::Result<()> {
web::post().to(accommodations_list_controller::create), web::post().to(accommodations_list_controller::create),
) )
// TODO : update // TODO : update
// TODO : delete .route(
"/family/{id}/accommodations/list/{accommodation_id}",
web::delete().to(accommodations_list_controller::delete),
)
// TODO : list // TODO : list
// TODO : get single
// [ACCOMODATIONS] Reservations controller // [ACCOMODATIONS] Reservations controller
// TODO : create // TODO : create
// TODO : update // TODO : update

View File

@ -463,6 +463,10 @@ impl Accommodation {
pub fn id(&self) -> AccommodationID { pub fn id(&self) -> AccommodationID {
AccommodationID(self.id) AccommodationID(self.id)
} }
pub fn family_id(&self) -> FamilyID {
FamilyID(self.family_id)
}
} }
#[derive(Insertable)] #[derive(Insertable)]