Add endpoint to copy shift plan week
This commit is contained in:
parent
e7af89f1cd
commit
f894bf325d
4 changed files with 102 additions and 2 deletions
|
|
@ -1,14 +1,15 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use axum::body::Body;
|
use axum::body::Body;
|
||||||
use axum::extract::Path;
|
use axum::extract::{Path, Query};
|
||||||
use axum::routing::{delete, get, post};
|
use axum::routing::{delete, get, post};
|
||||||
use axum::{extract::State, response::Response};
|
use axum::{extract::State, response::Response};
|
||||||
use axum::{Extension, Json, Router};
|
use axum::{Extension, Json, Router};
|
||||||
use rest_types::BookingTO;
|
use rest_types::BookingTO;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::{error_handler, Context, RestStateDef};
|
use crate::{error_handler, Context, RestError, RestStateDef};
|
||||||
use service::booking::{Booking, BookingService};
|
use service::booking::{Booking, BookingService};
|
||||||
|
|
||||||
pub fn generate_route<RestState: RestStateDef>() -> Router<RestState> {
|
pub fn generate_route<RestState: RestStateDef>() -> Router<RestState> {
|
||||||
|
|
@ -18,6 +19,7 @@ pub fn generate_route<RestState: RestStateDef>() -> Router<RestState> {
|
||||||
.route("/:id", get(get_booking::<RestState>))
|
.route("/:id", get(get_booking::<RestState>))
|
||||||
.route("/", post(create_booking::<RestState>))
|
.route("/", post(create_booking::<RestState>))
|
||||||
.route("/:id", delete(delete_booking::<RestState>))
|
.route("/:id", delete(delete_booking::<RestState>))
|
||||||
|
.route("/copy", post(copy_calendar_week::<RestState>))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_all_bookings<RestState: RestStateDef>(
|
pub async fn get_all_bookings<RestState: RestStateDef>(
|
||||||
|
|
@ -109,6 +111,39 @@ pub async fn create_booking<RestState: RestStateDef>(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn copy_calendar_week<RestState: RestStateDef>(
|
||||||
|
rest_state: State<RestState>,
|
||||||
|
Extension(context): Extension<Context>,
|
||||||
|
Query(params): Query<HashMap<String, String>>,
|
||||||
|
) -> Response {
|
||||||
|
error_handler(
|
||||||
|
(async {
|
||||||
|
let from_year = params
|
||||||
|
.get("from_year")
|
||||||
|
.ok_or_else(|| RestError::BadRequest("year missing".to_string()))?
|
||||||
|
.parse()?;
|
||||||
|
let from_week = params
|
||||||
|
.get("from_week")
|
||||||
|
.ok_or_else(|| RestError::BadRequest("week missing".to_string()))?
|
||||||
|
.parse()?;
|
||||||
|
let to_year = params
|
||||||
|
.get("to_year")
|
||||||
|
.ok_or_else(|| RestError::BadRequest("year missing".to_string()))?
|
||||||
|
.parse()?;
|
||||||
|
let to_week = params
|
||||||
|
.get("to_week")
|
||||||
|
.ok_or_else(|| RestError::BadRequest("week missing".to_string()))?
|
||||||
|
.parse()?;
|
||||||
|
rest_state
|
||||||
|
.booking_service()
|
||||||
|
.copy_week(from_week, from_year, to_week, to_year, context.into())
|
||||||
|
.await?;
|
||||||
|
Ok(Response::builder().status(200).body(Body::empty()).unwrap())
|
||||||
|
})
|
||||||
|
.await,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn delete_booking<RestState: RestStateDef>(
|
pub async fn delete_booking<RestState: RestStateDef>(
|
||||||
rest_state: State<RestState>,
|
rest_state: State<RestState>,
|
||||||
Extension(context): Extension<Context>,
|
Extension(context): Extension<Context>,
|
||||||
|
|
|
||||||
|
|
@ -107,6 +107,12 @@ pub enum RestError {
|
||||||
|
|
||||||
#[error("Inconsistent id. Got {0} in path but {1} in body")]
|
#[error("Inconsistent id. Got {0} in path but {1} in body")]
|
||||||
InconsistentId(Uuid, Uuid),
|
InconsistentId(Uuid, Uuid),
|
||||||
|
|
||||||
|
#[error("Bad request: {0}")]
|
||||||
|
BadRequest(String),
|
||||||
|
|
||||||
|
#[error("Parse int error: {0}")]
|
||||||
|
ParseIntError(#[from] std::num::ParseIntError),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn error_handler(result: Result<Response, RestError>) -> Response {
|
fn error_handler(result: Result<Response, RestError>) -> Response {
|
||||||
|
|
@ -119,6 +125,14 @@ fn error_handler(result: Result<Response, RestError>) -> Response {
|
||||||
.status(400)
|
.status(400)
|
||||||
.body(Body::new(err.to_string()))
|
.body(Body::new(err.to_string()))
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
|
Err(err @ RestError::BadRequest(_)) => Response::builder()
|
||||||
|
.status(400)
|
||||||
|
.body(Body::new(err.to_string()))
|
||||||
|
.unwrap(),
|
||||||
|
Err(err @ RestError::ParseIntError(_)) => Response::builder()
|
||||||
|
.status(400)
|
||||||
|
.body(Body::new(err.to_string()))
|
||||||
|
.unwrap(),
|
||||||
Err(RestError::ServiceError(service::ServiceError::Forbidden)) => {
|
Err(RestError::ServiceError(service::ServiceError::Forbidden)) => {
|
||||||
Response::builder().status(403).body(Body::empty()).unwrap()
|
Response::builder().status(403).body(Body::empty()).unwrap()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,14 @@ pub trait BookingService {
|
||||||
booking: &Booking,
|
booking: &Booking,
|
||||||
context: Authentication<Self::Context>,
|
context: Authentication<Self::Context>,
|
||||||
) -> Result<Booking, ServiceError>;
|
) -> Result<Booking, ServiceError>;
|
||||||
|
async fn copy_week(
|
||||||
|
&self,
|
||||||
|
from_calendar_week: u8,
|
||||||
|
from_year: u32,
|
||||||
|
to_calendar_week: u8,
|
||||||
|
to_year: u32,
|
||||||
|
context: Authentication<Self::Context>,
|
||||||
|
) -> Result<(), ServiceError>;
|
||||||
async fn delete(
|
async fn delete(
|
||||||
&self,
|
&self,
|
||||||
id: Uuid,
|
id: Uuid,
|
||||||
|
|
|
||||||
|
|
@ -233,6 +233,49 @@ where
|
||||||
Ok(new_booking)
|
Ok(new_booking)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn copy_week(
|
||||||
|
&self,
|
||||||
|
from_calendar_week: u8,
|
||||||
|
from_year: u32,
|
||||||
|
to_calendar_week: u8,
|
||||||
|
to_year: u32,
|
||||||
|
context: Authentication<Self::Context>,
|
||||||
|
) -> Result<(), ServiceError> {
|
||||||
|
self.permission_service
|
||||||
|
.check_permission("hr", context.clone())
|
||||||
|
.await?;
|
||||||
|
let from_week = self
|
||||||
|
.get_for_week(from_calendar_week, from_year, Authentication::Full)
|
||||||
|
.await?;
|
||||||
|
let to_week = self
|
||||||
|
.get_for_week(to_calendar_week, to_year, Authentication::Full)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
// Remove entries which are already in the destination week
|
||||||
|
let to_week_ids: Arc<[(Uuid, Uuid)]> = to_week
|
||||||
|
.iter()
|
||||||
|
.map(|b| (b.sales_person_id, b.slot_id))
|
||||||
|
.collect();
|
||||||
|
let from_week: Arc<[Booking]> = from_week
|
||||||
|
.iter()
|
||||||
|
.filter(|b| !to_week_ids.contains(&(b.sales_person_id, b.slot_id)))
|
||||||
|
.map(|b| {
|
||||||
|
let mut new_booking = b.clone();
|
||||||
|
new_booking.id = Uuid::nil();
|
||||||
|
new_booking.calendar_week = to_calendar_week as i32;
|
||||||
|
new_booking.year = to_year;
|
||||||
|
new_booking.created = None;
|
||||||
|
new_booking.version = Uuid::nil();
|
||||||
|
new_booking
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
for booking in from_week.into_iter() {
|
||||||
|
self.create(booking, Authentication::Full).await?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
async fn delete(
|
async fn delete(
|
||||||
&self,
|
&self,
|
||||||
id: Uuid,
|
id: Uuid,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue