diff --git a/src/model.rs b/src/model.rs index e858e9a..824cf4a 100644 --- a/src/model.rs +++ b/src/model.rs @@ -1,4 +1,4 @@ -use serde::Serialize; +use serde::{Serialize, Deserialize}; #[derive(Serialize)] pub struct Room { @@ -21,6 +21,7 @@ pub struct Address { #[derive(Serialize)] pub struct Person { + pub id: i32, pub first_name: String, pub last_name: String, pub age: i32, @@ -57,4 +58,9 @@ pub struct CleaningPlan { pub date: String, pub duration: i32, pub room: Room, +} + +#[derive(Deserialize)] +pub struct BookingQuery { + pub months: Option, } \ No newline at end of file diff --git a/src/routes.rs b/src/routes.rs index b220758..33fcc25 100644 --- a/src/routes.rs +++ b/src/routes.rs @@ -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( Extension(service): Extension, @@ -9,9 +10,48 @@ async fn rooms( Ok(Json(rooms)) } +async fn bookings( + Query(query): Query, + Extension(service): Extension, +) -> Result { + 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, + Extension(service): Extension, +) -> Result { + 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, + Extension(service): Extension, +) -> Result { + let rooms = service.get_rooms_for_booking(id).await?; + Ok(Json(rooms)) +} + +async fn booking_guests( + Path(id): Path, + Extension(service): Extension, +) -> Result { + let guests = service.get_guests_for_booking(id).await?; + Ok(Json(guests)) +} pub fn routes() -> Router { Router::new() .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() } \ No newline at end of file diff --git a/src/sql.rs b/src/sql.rs index 307d501..125c76c 100644 --- a/src/sql.rs +++ b/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 { @@ -36,4 +36,178 @@ impl ServiceInner { Ok(rooms) } + pub async fn get_bookings(&self) -> Result, 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 = 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, 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 = 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, 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, 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 = 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, 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 = 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) + } + } \ No newline at end of file