Add an accommodations reservations module #188
@ -2,8 +2,69 @@ use crate::controllers::HttpResult;
|
|||||||
use crate::extractors::accommodation_extractor::FamilyAndAccommodationInPath;
|
use crate::extractors::accommodation_extractor::FamilyAndAccommodationInPath;
|
||||||
use crate::extractors::accommodation_reservation_extractor::FamilyAndAccommodationReservationInPath;
|
use crate::extractors::accommodation_reservation_extractor::FamilyAndAccommodationReservationInPath;
|
||||||
use crate::extractors::family_extractor::FamilyInPath;
|
use crate::extractors::family_extractor::FamilyInPath;
|
||||||
|
use crate::models::NewAccommodationReservation;
|
||||||
use crate::services::accommodations_reservations_service;
|
use crate::services::accommodations_reservations_service;
|
||||||
use actix_web::HttpResponse;
|
use crate::utils::time_utils::time;
|
||||||
|
use actix_web::{web, HttpResponse};
|
||||||
|
|
||||||
|
#[derive(serde::Deserialize)]
|
||||||
|
pub struct CreateReservationQuery {
|
||||||
|
start: usize,
|
||||||
|
end: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a reservation
|
||||||
|
pub async fn create_reservation(
|
||||||
|
a: FamilyAndAccommodationInPath,
|
||||||
|
req: web::Json<CreateReservationQuery>,
|
||||||
|
) -> HttpResult {
|
||||||
|
if !a.open_to_reservations {
|
||||||
|
return Ok(HttpResponse::ExpectationFailed()
|
||||||
|
.json("The accommodation is not open to reservations!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req.start as i64) < (time() as i64 - 3600 * 24 * 30) {
|
||||||
|
return Ok(HttpResponse::BadRequest().json("Start time is too far in the past!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if req.start > req.end {
|
||||||
|
return Ok(HttpResponse::BadRequest().json("End time happens before start time!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
let existing = accommodations_reservations_service::get_reservations_for_time_interval(
|
||||||
|
a.id(),
|
||||||
|
req.start,
|
||||||
|
req.end,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
if existing.iter().any(|r| r.validated != Some(false)) {
|
||||||
|
return Ok(
|
||||||
|
HttpResponse::Conflict().json("This reservation is in conflict with another one!")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut reservation =
|
||||||
|
accommodations_reservations_service::create(&NewAccommodationReservation {
|
||||||
|
family_id: a.family_id().0,
|
||||||
|
accommodation_id: a.id().0,
|
||||||
|
user_id: a.membership().user_id().0,
|
||||||
|
time_create: time() as i64,
|
||||||
|
time_update: time() as i64,
|
||||||
|
reservation_start: req.start as i64,
|
||||||
|
reservation_end: req.end as i64,
|
||||||
|
})
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
// Auto validate reservation if requested
|
||||||
|
if !a.need_validation {
|
||||||
|
reservation.validated = Some(true);
|
||||||
|
|
||||||
|
accommodations_reservations_service::update(&mut reservation).await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(HttpResponse::Ok().json(reservation))
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the reservations for a given accommodation
|
/// Get the reservations for a given accommodation
|
||||||
pub async fn get_accommodation_reservations(a: FamilyAndAccommodationInPath) -> HttpResult {
|
pub async fn get_accommodation_reservations(a: FamilyAndAccommodationInPath) -> HttpResult {
|
||||||
|
@ -236,7 +236,10 @@ async fn main() -> std::io::Result<()> {
|
|||||||
"/family/{id}/accommodations/reservations/full_list",
|
"/family/{id}/accommodations/reservations/full_list",
|
||||||
web::get().to(accommodations_reservations_controller::full_list),
|
web::get().to(accommodations_reservations_controller::full_list),
|
||||||
)
|
)
|
||||||
// TODO : create
|
.route(
|
||||||
|
"/family/{id}/accommodations/reservations/accommodation/{accommodation_id}/create",
|
||||||
|
web::post().to(accommodations_reservations_controller::create_reservation),
|
||||||
|
)
|
||||||
.route(
|
.route(
|
||||||
"/family/{id}/accommodations/reservation/{reservation_id}",
|
"/family/{id}/accommodations/reservation/{reservation_id}",
|
||||||
web::get().to(accommodations_reservations_controller::get_single),
|
web::get().to(accommodations_reservations_controller::get_single),
|
||||||
|
@ -1,10 +1,42 @@
|
|||||||
use crate::connections::db_connection;
|
use crate::connections::db_connection;
|
||||||
use crate::models::{
|
use crate::models::{
|
||||||
AccommodationID, AccommodationReservation, AccommodationReservationID, FamilyID,
|
AccommodationID, AccommodationReservation, AccommodationReservationID, FamilyID,
|
||||||
|
NewAccommodationReservation,
|
||||||
};
|
};
|
||||||
use crate::schema::accommodations_reservations;
|
use crate::schema::accommodations_reservations;
|
||||||
|
use crate::utils::time_utils::time;
|
||||||
use diesel::prelude::*;
|
use diesel::prelude::*;
|
||||||
|
|
||||||
|
/// Create a new reservation
|
||||||
|
pub async fn create(new: &NewAccommodationReservation) -> anyhow::Result<AccommodationReservation> {
|
||||||
|
db_connection::execute(|conn| {
|
||||||
|
let res: AccommodationReservation = diesel::insert_into(accommodations_reservations::table)
|
||||||
|
.values(new)
|
||||||
|
.get_result(conn)?;
|
||||||
|
|
||||||
|
Ok(res)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Update a reservation
|
||||||
|
pub async fn update(r: &mut AccommodationReservation) -> anyhow::Result<()> {
|
||||||
|
r.time_update = time() as i64;
|
||||||
|
|
||||||
|
db_connection::execute(|conn| {
|
||||||
|
diesel::update(
|
||||||
|
accommodations_reservations::dsl::accommodations_reservations
|
||||||
|
.filter(accommodations_reservations::dsl::id.eq(r.id().0)),
|
||||||
|
)
|
||||||
|
.set((
|
||||||
|
accommodations_reservations::dsl::time_update.eq(r.time_update),
|
||||||
|
accommodations_reservations::dsl::validated.eq(r.validated),
|
||||||
|
))
|
||||||
|
.execute(conn)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Get all the reservations of an accommodation
|
/// Get all the reservations of an accommodation
|
||||||
pub async fn get_all_of_accommodation(
|
pub async fn get_all_of_accommodation(
|
||||||
id: AccommodationID,
|
id: AccommodationID,
|
||||||
@ -33,3 +65,21 @@ pub async fn get_by_id(id: AccommodationReservationID) -> anyhow::Result<Accommo
|
|||||||
.get_result(conn)
|
.get_result(conn)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the reservations that are between a given interval of time for a given accommodation
|
||||||
|
pub async fn get_reservations_for_time_interval(
|
||||||
|
id: AccommodationID,
|
||||||
|
start: usize,
|
||||||
|
end: usize,
|
||||||
|
) -> anyhow::Result<Vec<AccommodationReservation>> {
|
||||||
|
db_connection::execute(|conn| {
|
||||||
|
accommodations_reservations::table
|
||||||
|
.filter(
|
||||||
|
accommodations_reservations::dsl::accommodation_id
|
||||||
|
.eq(id.0)
|
||||||
|
.and(accommodations_reservations::dsl::reservation_start.lt((end) as i64))
|
||||||
|
.and(accommodations_reservations::dsl::reservation_end.gt((start) as i64)),
|
||||||
|
)
|
||||||
|
.get_results(conn)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user