feat: GET endpoints for bookings
This commit is contained in:
parent
b29eb76b2d
commit
9a86e4866e
3 changed files with 224 additions and 4 deletions
|
@ -1,4 +1,4 @@
|
||||||
use serde::Serialize;
|
use serde::{Serialize, Deserialize};
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
pub struct Room {
|
pub struct Room {
|
||||||
|
@ -21,6 +21,7 @@ pub struct Address {
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
pub struct Person {
|
pub struct Person {
|
||||||
|
pub id: i32,
|
||||||
pub first_name: String,
|
pub first_name: String,
|
||||||
pub last_name: String,
|
pub last_name: String,
|
||||||
pub age: i32,
|
pub age: i32,
|
||||||
|
@ -57,4 +58,9 @@ pub struct CleaningPlan {
|
||||||
pub date: String,
|
pub date: String,
|
||||||
pub duration: i32,
|
pub duration: i32,
|
||||||
pub room: Room,
|
pub room: Room,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct BookingQuery {
|
||||||
|
pub months: Option<i32>,
|
||||||
}
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
use axum::{Router, routing::BoxRoute, extract::Extension, response::IntoResponse, Json, handler::get};
|
use axum::{Router, routing::BoxRoute, extract::{Extension, Path, Query}, response::IntoResponse, Json, handler::get};
|
||||||
|
use hyper::StatusCode;
|
||||||
|
|
||||||
use crate::{Service, error::ServiceError};
|
use crate::{Service, error::ServiceError, model::BookingQuery};
|
||||||
|
|
||||||
async fn rooms(
|
async fn rooms(
|
||||||
Extension(service): Extension<Service>,
|
Extension(service): Extension<Service>,
|
||||||
|
@ -9,9 +10,48 @@ async fn rooms(
|
||||||
Ok(Json(rooms))
|
Ok(Json(rooms))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn bookings(
|
||||||
|
Query(query): Query<BookingQuery>,
|
||||||
|
Extension(service): Extension<Service>,
|
||||||
|
) -> Result<impl IntoResponse, ServiceError> {
|
||||||
|
let bookings = match query.months {
|
||||||
|
Some(months) => service.get_last_bookings(months).await?,
|
||||||
|
None => service.get_bookings().await?,
|
||||||
|
};
|
||||||
|
Ok(Json(bookings))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn booking(
|
||||||
|
Path(id): Path<i32>,
|
||||||
|
Extension(service): Extension<Service>,
|
||||||
|
) -> Result<impl IntoResponse, ServiceError> {
|
||||||
|
let booking = service.get_booking(id).await?
|
||||||
|
.ok_or_else(|| ServiceError::ErrorResponse(StatusCode::NOT_FOUND, Some("booking not found".to_string())))?;
|
||||||
|
Ok(Json(booking))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn booking_rooms(
|
||||||
|
Path(id): Path<i32>,
|
||||||
|
Extension(service): Extension<Service>,
|
||||||
|
) -> Result<impl IntoResponse, ServiceError> {
|
||||||
|
let rooms = service.get_rooms_for_booking(id).await?;
|
||||||
|
Ok(Json(rooms))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn booking_guests(
|
||||||
|
Path(id): Path<i32>,
|
||||||
|
Extension(service): Extension<Service>,
|
||||||
|
) -> Result<impl IntoResponse, ServiceError> {
|
||||||
|
let guests = service.get_guests_for_booking(id).await?;
|
||||||
|
Ok(Json(guests))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn routes() -> Router<BoxRoute> {
|
pub fn routes() -> Router<BoxRoute> {
|
||||||
Router::new()
|
Router::new()
|
||||||
.route("/rooms", get(rooms))
|
.route("/rooms", get(rooms))
|
||||||
|
.route("/bookings", get(bookings))
|
||||||
|
.route("/bookings/:id", get(booking))
|
||||||
|
.route("/bookings/:id/rooms", get(booking_rooms))
|
||||||
|
.route("/bookings/:id/guests", get(booking_guests))
|
||||||
.boxed()
|
.boxed()
|
||||||
}
|
}
|
176
src/sql.rs
176
src/sql.rs
|
@ -1,4 +1,4 @@
|
||||||
use crate::{ServiceInner, model::Room, error::ServiceError};
|
use crate::{ServiceInner, model::{Room, Booking, Person, Address}, error::ServiceError};
|
||||||
|
|
||||||
impl ServiceInner {
|
impl ServiceInner {
|
||||||
|
|
||||||
|
@ -36,4 +36,178 @@ impl ServiceInner {
|
||||||
Ok(rooms)
|
Ok(rooms)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn get_bookings(&self) -> Result<Vec<Booking>, ServiceError> {
|
||||||
|
let session = self.pool.get_session().await?;
|
||||||
|
let stmt = session.prepare("
|
||||||
|
SELECT
|
||||||
|
bookingId,
|
||||||
|
arrivalDate,
|
||||||
|
departureDate,
|
||||||
|
cost,
|
||||||
|
pensionType,
|
||||||
|
clientId
|
||||||
|
FROM BOOKING
|
||||||
|
").await?;
|
||||||
|
|
||||||
|
let rows = stmt.query("").await?;
|
||||||
|
|
||||||
|
let mut bookings: Vec<Booking> = vec![];
|
||||||
|
|
||||||
|
while let Some(row) = rows.next().await? {
|
||||||
|
let booking = Booking {
|
||||||
|
id: row.get(0)?,
|
||||||
|
arrival_date: row.get(1)?,
|
||||||
|
depature_date: row.get(2)?,
|
||||||
|
cost: row.get(3)?,
|
||||||
|
pension_type: row.get(4)?,
|
||||||
|
client_id: row.get(5)?,
|
||||||
|
};
|
||||||
|
bookings.push(booking);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(bookings)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_last_bookings(&self, months: i32) -> Result<Vec<Booking>, ServiceError> {
|
||||||
|
let session = self.pool.get_session().await?;
|
||||||
|
let stmt = session.prepare("
|
||||||
|
SELECT
|
||||||
|
bookingId,
|
||||||
|
arrivalDate,
|
||||||
|
departureDate,
|
||||||
|
cost,
|
||||||
|
pensionType,
|
||||||
|
clientId
|
||||||
|
FROM table(getLastBookings(:MONTHS)) bkk
|
||||||
|
INNER JOIN BOOKING bk ON bkk.COLUMN_VALUE = bk.bookingId
|
||||||
|
").await?;
|
||||||
|
|
||||||
|
let rows = stmt.query(months).await?;
|
||||||
|
|
||||||
|
let mut bookings: Vec<Booking> = vec![];
|
||||||
|
|
||||||
|
while let Some(row) = rows.next().await? {
|
||||||
|
let booking = Booking {
|
||||||
|
id: row.get(0)?,
|
||||||
|
arrival_date: row.get(1)?,
|
||||||
|
depature_date: row.get(2)?,
|
||||||
|
cost: row.get(3)?,
|
||||||
|
pension_type: row.get(4)?,
|
||||||
|
client_id: row.get(5)?,
|
||||||
|
};
|
||||||
|
bookings.push(booking);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(bookings)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_booking(&self, id: i32) -> Result<Option<Booking>, ServiceError> {
|
||||||
|
let session = self.pool.get_session().await?;
|
||||||
|
let stmt = session.prepare("
|
||||||
|
SELECT
|
||||||
|
bookingId,
|
||||||
|
arrivalDate,
|
||||||
|
departureDate,
|
||||||
|
cost,
|
||||||
|
pensionType,
|
||||||
|
clientId
|
||||||
|
FROM BOOKING WHERE bookingId = :ID
|
||||||
|
").await?;
|
||||||
|
|
||||||
|
let row = stmt.query_single(id).await?;
|
||||||
|
|
||||||
|
Ok(match row {
|
||||||
|
Some(row) => {
|
||||||
|
Some(Booking {
|
||||||
|
id: row.get(0)?,
|
||||||
|
arrival_date: row.get(1)?,
|
||||||
|
depature_date: row.get(2)?,
|
||||||
|
cost: row.get(3)?,
|
||||||
|
pension_type: row.get(4)?,
|
||||||
|
client_id: row.get(5)?,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
None => None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_rooms_for_booking(&self, booking: i32) -> Result<Vec<Room>, ServiceError> {
|
||||||
|
let session = self.pool.get_session().await?;
|
||||||
|
let stmt = session.prepare("
|
||||||
|
SELECT
|
||||||
|
r.roomNumber,
|
||||||
|
floor,
|
||||||
|
roomTyp,
|
||||||
|
\"size\",
|
||||||
|
accessibility,
|
||||||
|
beds
|
||||||
|
FROM room r
|
||||||
|
INNER JOIN BookingRoom br ON r.roomNumber = br.roomNumber
|
||||||
|
WHERE br.bookingId = :BOOKING
|
||||||
|
").await?;
|
||||||
|
|
||||||
|
let rows = stmt.query(booking).await?;
|
||||||
|
|
||||||
|
let mut rooms: Vec<Room> = vec![];
|
||||||
|
|
||||||
|
while let Some(row) = rows.next().await? {
|
||||||
|
|
||||||
|
let acc: i32 = row.get(5)?;
|
||||||
|
let room = Room {
|
||||||
|
room_number: row.get(0)?,
|
||||||
|
floor: row.get(1)?,
|
||||||
|
size: row.get(3)?,
|
||||||
|
room_type: row.get(2)?,
|
||||||
|
beds: row.get(4)?,
|
||||||
|
accessibility: acc != 0,
|
||||||
|
};
|
||||||
|
rooms.push(room);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(rooms)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_guests_for_booking(&self, booking: i32) -> Result<Vec<Person>, ServiceError> {
|
||||||
|
let session = self.pool.get_session().await?;
|
||||||
|
let stmt = session.prepare("
|
||||||
|
SELECT
|
||||||
|
p.personId,
|
||||||
|
p.name,
|
||||||
|
p.lastName,
|
||||||
|
p.age,
|
||||||
|
ad.street,
|
||||||
|
ad.houseNumber,
|
||||||
|
ad.postalCode,
|
||||||
|
ad.city,
|
||||||
|
ad.country
|
||||||
|
FROM person p
|
||||||
|
INNER JOIN Address ad ON p.addressId = ad.addressId
|
||||||
|
INNER JOIN BookingGuest bg ON p.personId = bg.personId
|
||||||
|
WHERE bg.bookingId = :BOOKING
|
||||||
|
").await?;
|
||||||
|
|
||||||
|
let rows = stmt.query(booking).await?;
|
||||||
|
|
||||||
|
let mut persons: Vec<Person> = vec![];
|
||||||
|
|
||||||
|
while let Some(row) = rows.next().await? {
|
||||||
|
let person = Person {
|
||||||
|
id: row.get(0)?,
|
||||||
|
first_name: row.get(1)?,
|
||||||
|
last_name: row.get(2)?,
|
||||||
|
age: row.get(3)?,
|
||||||
|
address: Address {
|
||||||
|
street: row.get(4)?,
|
||||||
|
house_number: row.get(5)?,
|
||||||
|
postal_code: row.get(6)?,
|
||||||
|
city: row.get(7)?,
|
||||||
|
country: row.get(8)?,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
persons.push(person);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(persons)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in a new issue