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 axum::body::Body;
|
||||
use axum::extract::Path;
|
||||
use axum::extract::{Path, Query};
|
||||
use axum::routing::{delete, get, post};
|
||||
use axum::{extract::State, response::Response};
|
||||
use axum::{Extension, Json, Router};
|
||||
use rest_types::BookingTO;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{error_handler, Context, RestStateDef};
|
||||
use crate::{error_handler, Context, RestError, RestStateDef};
|
||||
use service::booking::{Booking, BookingService};
|
||||
|
||||
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("/", post(create_booking::<RestState>))
|
||||
.route("/:id", delete(delete_booking::<RestState>))
|
||||
.route("/copy", post(copy_calendar_week::<RestState>))
|
||||
}
|
||||
|
||||
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>(
|
||||
rest_state: State<RestState>,
|
||||
Extension(context): Extension<Context>,
|
||||
|
|
|
|||
|
|
@ -107,6 +107,12 @@ pub enum RestError {
|
|||
|
||||
#[error("Inconsistent id. Got {0} in path but {1} in body")]
|
||||
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 {
|
||||
|
|
@ -119,6 +125,14 @@ fn error_handler(result: Result<Response, RestError>) -> Response {
|
|||
.status(400)
|
||||
.body(Body::new(err.to_string()))
|
||||
.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)) => {
|
||||
Response::builder().status(403).body(Body::empty()).unwrap()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,6 +75,14 @@ pub trait BookingService {
|
|||
booking: &Booking,
|
||||
context: Authentication<Self::Context>,
|
||||
) -> 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(
|
||||
&self,
|
||||
id: Uuid,
|
||||
|
|
|
|||
|
|
@ -233,6 +233,49 @@ where
|
|||
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(
|
||||
&self,
|
||||
id: Uuid,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue