feat: more clerk endpoints
This commit is contained in:
parent
fc2e993d31
commit
b8e64e2d2c
8 changed files with 267 additions and 117 deletions
|
@ -63,6 +63,6 @@ async fn main() -> Result<(), ApplicationError> {
|
|||
async fn shutdown() {
|
||||
match signal::ctrl_c().await {
|
||||
Ok(()) => {},
|
||||
Err(err) => {},
|
||||
Err(_) => {},
|
||||
}
|
||||
}
|
|
@ -72,6 +72,11 @@ pub struct BookingQuery {
|
|||
pub months: Option<i32>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct ClerkMonthsQuery {
|
||||
pub months: i32,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct BookingBody {
|
||||
|
|
|
@ -1,31 +1,7 @@
|
|||
use axum::{Router, routing::BoxRoute, extract::{Extension, Path, Query}, response::IntoResponse, Json, handler::{get, put}};
|
||||
use axum::{Json, extract::{Path, Extension, Query}, response::IntoResponse, Router, routing::BoxRoute, handler::{get, put}};
|
||||
use hyper::StatusCode;
|
||||
|
||||
use crate::{Service, error::ServiceError, model::{BookingQuery, BookingBody, Booking}};
|
||||
|
||||
async fn rooms(
|
||||
Extension(service): Extension<Service>,
|
||||
) -> Result<impl IntoResponse, ServiceError> {
|
||||
let rooms = service.get_rooms().await?;
|
||||
Ok(Json(rooms))
|
||||
}
|
||||
|
||||
async fn room(
|
||||
Path(id): Path<i32>,
|
||||
Extension(service): Extension<Service>,
|
||||
) -> Result<impl IntoResponse, ServiceError> {
|
||||
let room = service.get_room(id).await?
|
||||
.ok_or_else(|| ServiceError::ErrorResponse(StatusCode::NOT_FOUND, Some("room not found".to_string())))?;
|
||||
Ok(Json(room))
|
||||
}
|
||||
|
||||
async fn cleaning_plans(
|
||||
Path(id): Path<i32>,
|
||||
Extension(service): Extension<Service>,
|
||||
) -> Result<impl IntoResponse, ServiceError> {
|
||||
let cleaning_plans = service.get_room_cleaning_plans(id).await?;
|
||||
Ok(Json(cleaning_plans))
|
||||
}
|
||||
use crate::{Service, error::ServiceError, model::{BookingBody, Booking, BookingQuery}};
|
||||
|
||||
async fn bookings(
|
||||
Query(query): Query<BookingQuery>,
|
||||
|
@ -128,24 +104,13 @@ async fn update_booking(
|
|||
Ok(StatusCode::NO_CONTENT)
|
||||
}
|
||||
|
||||
async fn clerks(
|
||||
Extension(service): Extension<Service>,
|
||||
) -> Result<impl IntoResponse, ServiceError> {
|
||||
let clerks = service.get_clerks().await?;
|
||||
Ok(Json(clerks))
|
||||
}
|
||||
|
||||
pub fn routes() -> Router<BoxRoute> {
|
||||
Router::new()
|
||||
.route("/rooms", get(rooms))
|
||||
.route("/rooms/:id", get(room))
|
||||
.route("/rooms/:id/cleaningPlans", get(cleaning_plans))
|
||||
.route("/bookings", get(bookings).post(add_booking))
|
||||
.route("/bookings/:id", get(booking).delete(delete_booking).put(update_booking))
|
||||
.route("/bookings/:id/rooms", get(booking_rooms))
|
||||
.route("/bookings/:id/rooms/:roomid", put(add_booking_room).delete(delete_booking_room))
|
||||
.route("/bookings/:id/guests", get(booking_guests))
|
||||
.route("/bookings/:id/guests/:personid", put(add_booking_guest).delete(delete_booking_guest))
|
||||
.route("/clerks", get(clerks))
|
||||
.route("/", get(bookings).post(add_booking))
|
||||
.route("/:id", get(booking).delete(delete_booking).put(update_booking))
|
||||
.route("/:id/rooms", get(booking_rooms))
|
||||
.route("/:id/rooms/:roomid", put(add_booking_room).delete(delete_booking_room))
|
||||
.route("/:id/guests", get(booking_guests))
|
||||
.route("/:id/guests/:personid", put(add_booking_guest).delete(delete_booking_guest))
|
||||
.boxed()
|
||||
}
|
37
src/routes/clerks.rs
Normal file
37
src/routes/clerks.rs
Normal file
|
@ -0,0 +1,37 @@
|
|||
use axum::{extract::{Extension, Query, Path}, response::IntoResponse, Json, routing::BoxRoute, Router, handler::get};
|
||||
use hyper::StatusCode;
|
||||
|
||||
use crate::{error::ServiceError, Service, model::ClerkMonthsQuery};
|
||||
|
||||
async fn clerks(
|
||||
Extension(service): Extension<Service>,
|
||||
) -> Result<impl IntoResponse, ServiceError> {
|
||||
let clerks = service.get_clerks().await?;
|
||||
Ok(Json(clerks))
|
||||
}
|
||||
|
||||
async fn clerk(
|
||||
Path(id): Path<i32>,
|
||||
Extension(service): Extension<Service>,
|
||||
) -> Result<impl IntoResponse, ServiceError> {
|
||||
let clerk = service.get_clerk(id).await?
|
||||
.ok_or_else(|| ServiceError::ErrorResponse(StatusCode::NOT_FOUND, Some("clerk not found".to_string())))?;
|
||||
Ok(Json(clerk))
|
||||
}
|
||||
|
||||
async fn most_valuable_clerk(
|
||||
Query(query): Query<ClerkMonthsQuery>,
|
||||
Extension(service): Extension<Service>,
|
||||
) -> Result<impl IntoResponse, ServiceError> {
|
||||
let clerk = service.get_most_valuable_clerk(query.months).await?
|
||||
.ok_or_else(|| ServiceError::ErrorResponse(StatusCode::NOT_FOUND, Some("clerk not found".to_string())))?;
|
||||
Ok(Json(clerk))
|
||||
}
|
||||
|
||||
pub fn routes() -> Router<BoxRoute> {
|
||||
Router::new()
|
||||
.route("/", get(clerks))
|
||||
.route("/:id", get(clerk))
|
||||
.route("/mostValuable", get(most_valuable_clerk))
|
||||
.boxed()
|
||||
}
|
13
src/routes/mod.rs
Normal file
13
src/routes/mod.rs
Normal file
|
@ -0,0 +1,13 @@
|
|||
use axum::{Router, routing::BoxRoute};
|
||||
|
||||
mod rooms;
|
||||
mod clerks;
|
||||
mod bookings;
|
||||
|
||||
pub fn routes() -> Router<BoxRoute> {
|
||||
Router::new()
|
||||
.nest("/rooms", rooms::routes())
|
||||
.nest("/bookings", bookings::routes())
|
||||
.nest("/clerks", clerks::routes())
|
||||
.boxed()
|
||||
}
|
36
src/routes/rooms.rs
Normal file
36
src/routes/rooms.rs
Normal file
|
@ -0,0 +1,36 @@
|
|||
use axum::{extract::{Extension, Path}, response::IntoResponse, Json, Router, routing::BoxRoute, handler::get};
|
||||
use hyper::StatusCode;
|
||||
|
||||
use crate::{error::ServiceError, Service};
|
||||
|
||||
async fn rooms(
|
||||
Extension(service): Extension<Service>,
|
||||
) -> Result<impl IntoResponse, ServiceError> {
|
||||
let rooms = service.get_rooms().await?;
|
||||
Ok(Json(rooms))
|
||||
}
|
||||
|
||||
async fn room(
|
||||
Path(id): Path<i32>,
|
||||
Extension(service): Extension<Service>,
|
||||
) -> Result<impl IntoResponse, ServiceError> {
|
||||
let room = service.get_room(id).await?
|
||||
.ok_or_else(|| ServiceError::ErrorResponse(StatusCode::NOT_FOUND, Some("room not found".to_string())))?;
|
||||
Ok(Json(room))
|
||||
}
|
||||
|
||||
async fn cleaning_plans(
|
||||
Path(id): Path<i32>,
|
||||
Extension(service): Extension<Service>,
|
||||
) -> Result<impl IntoResponse, ServiceError> {
|
||||
let cleaning_plans = service.get_room_cleaning_plans(id).await?;
|
||||
Ok(Json(cleaning_plans))
|
||||
}
|
||||
|
||||
pub fn routes() -> Router<BoxRoute> {
|
||||
Router::new()
|
||||
.route("/", get(rooms))
|
||||
.route("/:id", get(room))
|
||||
.route("/:id/cleaningPlans", get(cleaning_plans))
|
||||
.boxed()
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
use hyper::StatusCode;
|
||||
|
||||
use crate::{ServiceInner, model::{Room, Booking, Person, Address, BookingBody}, error::ServiceError};
|
||||
use crate::{ServiceInner, model::{Booking, BookingBody, Room, Person, Address}, error::ServiceError};
|
||||
|
||||
impl ServiceInner {
|
||||
|
||||
|
@ -99,6 +99,78 @@ impl ServiceInner {
|
|||
})
|
||||
}
|
||||
|
||||
pub async fn add_booking(&self, booking: BookingBody) -> Result<i32, ServiceError> {
|
||||
let session = self.pool.get_session().await?;
|
||||
let stmt = session.prepare("
|
||||
INSERT INTO BOOKING
|
||||
(
|
||||
bookingId,
|
||||
arrivalDate,
|
||||
departureDate,
|
||||
cost,
|
||||
pensionType,
|
||||
lateCheckout,
|
||||
clientId
|
||||
)
|
||||
VALUES
|
||||
(
|
||||
BOOKING_SEQ.nextval,
|
||||
TO_DATE(:ARRDATE, 'YYYY-MM-DD'),
|
||||
TO_DATE(:DEPDATE, 'YYYY-MM-DD'),
|
||||
:COST,
|
||||
:PENSION,
|
||||
0,
|
||||
:CLIENT
|
||||
)
|
||||
").await?;
|
||||
stmt.execute((
|
||||
(":ARRDATE", booking.arrival_date),
|
||||
(":DEPDATE", booking.depature_date),
|
||||
(":COST", booking.cost),
|
||||
(":PENSION", booking.pension_type),
|
||||
(":CLIENT", booking.client_id)
|
||||
)).await?;
|
||||
let stmt = session.prepare("SELECT BOOKING_SEQ.currval FROM dual").await?;
|
||||
let row = stmt.query_single("").await?
|
||||
.ok_or_else(|| ServiceError::ErrorResponse(StatusCode::INTERNAL_SERVER_ERROR, None))?;
|
||||
let id: i32 = row.get(0)?;
|
||||
session.commit().await?;
|
||||
Ok(id)
|
||||
}
|
||||
|
||||
pub async fn delete_booking(&self, booking: i32) -> Result<(), ServiceError> {
|
||||
let session = self.pool.get_session().await?;
|
||||
let stmt = session.prepare("
|
||||
DELETE FROM Booking WHERE bookingId = :BOOKING
|
||||
").await?;
|
||||
stmt.execute(booking).await?;
|
||||
session.commit().await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn update_booking(&self, id: i32, booking: BookingBody) -> Result<(), ServiceError> {
|
||||
let session = self.pool.get_session().await?;
|
||||
let stmt = session.prepare("
|
||||
UPDATE BOOKING SET
|
||||
arrivalDate = TO_DATE(:ARRDATE, 'YYYY-MM-DD'),
|
||||
departureDate = TO_DATE(:DEPDATE, 'YYYY-MM-DD'),
|
||||
cost = :COST,
|
||||
pensionType = :PENSION,
|
||||
clientId = :CLIENT
|
||||
WHERE bookingId = :ID
|
||||
").await?;
|
||||
stmt.execute((
|
||||
(":ID", id),
|
||||
(":ARRDATE", booking.arrival_date),
|
||||
(":DEPDATE", booking.depature_date),
|
||||
(":COST", booking.cost),
|
||||
(":PENSION", booking.pension_type),
|
||||
(":CLIENT", booking.client_id)
|
||||
)).await?;
|
||||
session.commit().await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
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("
|
||||
|
@ -218,76 +290,4 @@ impl ServiceInner {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn add_booking(&self, booking: BookingBody) -> Result<i32, ServiceError> {
|
||||
let session = self.pool.get_session().await?;
|
||||
let stmt = session.prepare("
|
||||
INSERT INTO BOOKING
|
||||
(
|
||||
bookingId,
|
||||
arrivalDate,
|
||||
departureDate,
|
||||
cost,
|
||||
pensionType,
|
||||
lateCheckout,
|
||||
clientId
|
||||
)
|
||||
VALUES
|
||||
(
|
||||
BOOKING_SEQ.nextval,
|
||||
TO_DATE(:ARRDATE, 'YYYY-MM-DD'),
|
||||
TO_DATE(:DEPDATE, 'YYYY-MM-DD'),
|
||||
:COST,
|
||||
:PENSION,
|
||||
0,
|
||||
:CLIENT
|
||||
)
|
||||
").await?;
|
||||
stmt.execute((
|
||||
(":ARRDATE", booking.arrival_date),
|
||||
(":DEPDATE", booking.depature_date),
|
||||
(":COST", booking.cost),
|
||||
(":PENSION", booking.pension_type),
|
||||
(":CLIENT", booking.client_id)
|
||||
)).await?;
|
||||
let stmt = session.prepare("SELECT BOOKING_SEQ.currval FROM dual").await?;
|
||||
let row = stmt.query_single("").await?
|
||||
.ok_or_else(|| ServiceError::ErrorResponse(StatusCode::INTERNAL_SERVER_ERROR, None))?;
|
||||
let id: i32 = row.get(0)?;
|
||||
session.commit().await?;
|
||||
Ok(id)
|
||||
}
|
||||
|
||||
pub async fn delete_booking(&self, booking: i32) -> Result<(), ServiceError> {
|
||||
let session = self.pool.get_session().await?;
|
||||
let stmt = session.prepare("
|
||||
DELETE FROM Booking WHERE bookingId = :BOOKING
|
||||
").await?;
|
||||
stmt.execute(booking).await?;
|
||||
session.commit().await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn update_booking(&self, id: i32, booking: BookingBody) -> Result<(), ServiceError> {
|
||||
let session = self.pool.get_session().await?;
|
||||
let stmt = session.prepare("
|
||||
UPDATE BOOKING SET
|
||||
arrivalDate = TO_DATE(:ARRDATE, 'YYYY-MM-DD'),
|
||||
departureDate = TO_DATE(:DEPDATE, 'YYYY-MM-DD'),
|
||||
cost = :COST,
|
||||
pensionType = :PENSION,
|
||||
clientId = :CLIENT
|
||||
WHERE bookingId = :ID
|
||||
").await?;
|
||||
stmt.execute((
|
||||
(":ID", id),
|
||||
(":ARRDATE", booking.arrival_date),
|
||||
(":DEPDATE", booking.depature_date),
|
||||
(":COST", booking.cost),
|
||||
(":PENSION", booking.pension_type),
|
||||
(":CLIENT", booking.client_id)
|
||||
)).await?;
|
||||
session.commit().await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
}
|
|
@ -50,4 +50,98 @@ impl ServiceInner {
|
|||
Ok(clerks)
|
||||
}
|
||||
|
||||
pub async fn get_clerk(&self, id: i32) -> Result<Option<Clerk>, ServiceError> {
|
||||
let session = self.pool.get_session().await?;
|
||||
let stmt = session.prepare("
|
||||
SELECT
|
||||
c.staff,
|
||||
c.salary,
|
||||
p.personId,
|
||||
p.name,
|
||||
p.lastName,
|
||||
p.age,
|
||||
ad.street,
|
||||
ad.houseNumber,
|
||||
ad.postalCode,
|
||||
ad.city,
|
||||
ad.country
|
||||
FROM Clerk c
|
||||
INNER JOIN Person p ON p.personId = c.personId
|
||||
INNER JOIN Address ad ON p.addressId = ad.addressId
|
||||
WHERE c.staff = :ID
|
||||
").await?;
|
||||
|
||||
let row = stmt.query_single(id).await?;
|
||||
|
||||
Ok(match row {
|
||||
Some(row) => {
|
||||
Some(Clerk {
|
||||
staff_number: row.get(0)?,
|
||||
salary: row.get(1)?,
|
||||
person_data: Person {
|
||||
id: row.get(2)?,
|
||||
first_name: row.get(3)?,
|
||||
last_name: row.get(4)?,
|
||||
age: row.get(5)?,
|
||||
address: Address {
|
||||
street: row.get(6)?,
|
||||
house_number: row.get(7)?,
|
||||
postal_code: row.get(8)?,
|
||||
city: row.get(9)?,
|
||||
country: row.get(10)?,
|
||||
},
|
||||
},
|
||||
})
|
||||
},
|
||||
None => None,
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn get_most_valuable_clerk(&self, months: i32) -> Result<Option<Clerk>, ServiceError> {
|
||||
let session = self.pool.get_session().await?;
|
||||
let stmt = session.prepare("
|
||||
SELECT
|
||||
c.staff,
|
||||
c.salary,
|
||||
p.personId,
|
||||
p.name,
|
||||
p.lastName,
|
||||
p.age,
|
||||
ad.street,
|
||||
ad.houseNumber,
|
||||
ad.postalCode,
|
||||
ad.city,
|
||||
ad.country
|
||||
FROM Clerk c
|
||||
INNER JOIN Person p ON p.personId = c.personId
|
||||
INNER JOIN Address ad ON p.addressId = ad.addressId
|
||||
WHERE p.personId = mostValuableClerk(:MONTHS)
|
||||
").await?;
|
||||
|
||||
let row = stmt.query_single(months).await?;
|
||||
|
||||
Ok(match row {
|
||||
Some(row) => {
|
||||
Some(Clerk {
|
||||
staff_number: row.get(0)?,
|
||||
salary: row.get(1)?,
|
||||
person_data: Person {
|
||||
id: row.get(2)?,
|
||||
first_name: row.get(3)?,
|
||||
last_name: row.get(4)?,
|
||||
age: row.get(5)?,
|
||||
address: Address {
|
||||
street: row.get(6)?,
|
||||
house_number: row.get(7)?,
|
||||
postal_code: row.get(8)?,
|
||||
city: row.get(9)?,
|
||||
country: row.get(10)?,
|
||||
},
|
||||
},
|
||||
})
|
||||
},
|
||||
None => None,
|
||||
})
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue