Skip to content

Commit

Permalink
editoast: adapt timetable endpoint and delete post endpoint
Browse files Browse the repository at this point in the history
Signed-off-by: Youness CHRIFI ALAOUI <[email protected]>
  • Loading branch information
younesschrifi committed Feb 4, 2025
1 parent 586b13c commit c58e8bb
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 166 deletions.
42 changes: 6 additions & 36 deletions editoast/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2719,27 +2719,6 @@ paths:
'404':
description: Timetable not found
/timetable/{id}:
get:
tags:
- timetable
summary: Return a specific timetable with its associated schedules
parameters:
- name: id
in: path
description: A timetable ID
required: true
schema:
type: integer
format: int64
responses:
'200':
description: Timetable with train schedules ids
content:
application/json:
schema:
$ref: '#/components/schemas/TimetableDetailedResult'
'404':
description: Timetable not found
delete:
tags:
- timetable
Expand Down Expand Up @@ -2986,11 +2965,10 @@ paths:
enum:
- preprocessing_simulation_error
/timetable/{id}/train_schedule:
post:
get:
tags:
- timetable
- train_schedule
summary: Create train schedule by batch
summary: Return a specific timetable with its associated schedules
parameters:
- name: id
in: path
Expand All @@ -2999,23 +2977,15 @@ paths:
schema:
type: integer
format: int64
requestBody:
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/TrainScheduleBase'
required: true
responses:
'200':
description: The created train schedules
description: Timetable with train schedules ids
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/TrainScheduleResult'
$ref: '#/components/schemas/TimetableDetailedResult'
'404':
description: Timetable not found
/towed_rolling_stock:
get:
tags:
Expand Down
14 changes: 14 additions & 0 deletions editoast/src/models/timetable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,20 @@ impl Timetable {
.map_err(Into::into)
}

pub async fn trains_from_timetable_id(timetable_id: i64, conn: &mut DbConnection) -> Result<Vec<TrainSchedule>> {
use editoast_models::tables::train_schedule::dsl;
use diesel::prelude::*;
use diesel_async::RunQueryDsl;


dsl::train_schedule.filter(dsl::timetable_id.eq(timetable_id))
.load_stream::<Row<TrainSchedule>>(conn.write().await.deref_mut())
.await?
.map_ok(|ts| ts.into())
.try_collect::<Vec<TrainSchedule>>()
.await.map_err(Into::into)
}

pub async fn gather_start_times(
timetable_id: i64,
conn: &mut DbConnection,
Expand Down
86 changes: 31 additions & 55 deletions editoast/src/views/timetable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ use axum::Extension;
use derivative::Derivative;
use editoast_authz::BuiltinRole;
use editoast_derive::EditoastError;
use editoast_schemas::train_schedule::TrainScheduleBase;
use itertools::Itertools;
use serde::Deserialize;
use serde::Serialize;
Expand All @@ -30,25 +29,26 @@ use crate::models::prelude::*;
use crate::models::timetable::Timetable;
use crate::models::timetable::TimetableWithTrains;
use crate::models::train_schedule::TrainSchedule;
use crate::models::train_schedule::TrainScheduleChangeset;
use crate::models::Infra;
use crate::views::train_schedule::train_simulation_batch;
use crate::views::train_schedule::TrainScheduleForm;
use crate::views::train_schedule::TrainScheduleResult;
use crate::views::AuthenticationExt;
use crate::views::AuthorizationError;
use crate::AppState;
use crate::RetrieveBatch;
use editoast_models::DbConnectionPoolV2;

use super::pagination::PaginatedList as _;
use super::pagination::PaginationQueryParams;
use super::pagination::PaginationStats;

crate::routes! {
"/timetable" => {
post,
"/{id}" => {
delete,
get,
"/conflicts" => conflicts,
"/train_schedule" => train_schedule,
&stdcm,
},
},
Expand Down Expand Up @@ -114,7 +114,7 @@ struct TimetableIdParam {

/// Return a specific timetable with its associated schedules
#[utoipa::path(
get, path = "",
get, path = "/train_schedule",
tag = "timetable",
params(TimetableIdParam),
responses(
Expand All @@ -126,21 +126,41 @@ async fn get(
State(db_pool): State<DbConnectionPoolV2>,
Extension(auth): AuthenticationExt,
Path(TimetableIdParam { id: timetable_id }): Path<TimetableIdParam>,
) -> Result<Json<TimetableDetailedResult>> {
Query(pagination_params): Query<PaginationQueryParams>,
) -> Result<Json<ListTrainSchedulesResponse>> {
let authorized = auth
.check_roles([BuiltinRole::TimetableRead].into())
.await
.map_err(AuthorizationError::AuthError)?;
.check_roles([BuiltinRole::TimetableRead].into())
.await
.map_err(AuthorizationError::AuthError)?;
if !authorized {
return Err(AuthorizationError::Forbidden.into());
}

let conn = &mut db_pool.get().await?;
let timetable = TimetableWithTrains::retrieve_or_fail(conn, timetable_id, || {
Timetable::retrieve_or_fail(conn, timetable_id, || {
TimetableError::NotFound { timetable_id }
})
.await?;
Ok(Json(timetable.into()))

let settings = pagination_params
.validate(1000)?
.warn_page_size(100)
.into_selection_settings()
.filter(move || TrainSchedule::TIMETABLE_ID.eq(timetable_id));

let (train_schedules, stats) = TrainSchedule::list_paginated(conn, settings).await?;
let results = train_schedules.into_iter().map_into().collect();

Ok(Json(ListTrainSchedulesResponse {stats, results}))
}

#[derive(Serialize, ToSchema)]
#[cfg_attr(test, derive(Deserialize))]
struct ListTrainSchedulesResponse {
#[schema(value_type = Vec<TrainScheduleResult>)]
results: Vec<TrainScheduleResult>,
#[serde(flatten)]
stats: PaginationStats,
}

/// Create a timetable
Expand Down Expand Up @@ -202,50 +222,6 @@ async fn delete(
Ok(StatusCode::NO_CONTENT)
}

/// Create train schedule by batch
#[utoipa::path(
post, path = "",
tag = "timetable,train_schedule",
params(TimetableIdParam),
request_body = Vec<TrainScheduleBase>,
responses(
(status = 200, description = "The created train schedules", body = Vec<TrainScheduleResult>)
)
)]
async fn train_schedule(
State(db_pool): State<DbConnectionPoolV2>,
Extension(auth): AuthenticationExt,
Path(TimetableIdParam { id: timetable_id }): Path<TimetableIdParam>,
Json(train_schedules): Json<Vec<TrainScheduleBase>>,
) -> Result<Json<Vec<TrainScheduleResult>>> {
let authorized = auth
.check_roles([BuiltinRole::TimetableWrite].into())
.await
.map_err(AuthorizationError::AuthError)?;
if !authorized {
return Err(AuthorizationError::Forbidden.into());
}

let conn = &mut db_pool.get().await?;

TimetableWithTrains::retrieve_or_fail(conn, timetable_id, || TimetableError::NotFound {
timetable_id,
})
.await?;
let changesets: Vec<TrainScheduleChangeset> = train_schedules
.into_iter()
.map(|ts| TrainScheduleForm {
timetable_id: Some(timetable_id),
train_schedule: ts,
})
.map_into()
.collect();

// Create a batch of train_schedule
let train_schedule: Vec<_> = TrainSchedule::create_batch(conn, changesets).await?;
Ok(Json(train_schedule.into_iter().map_into().collect()))
}

#[derive(Debug, Default, Clone, Serialize, Deserialize, IntoParams, ToSchema)]
#[into_params(parameter_in = Query)]
pub struct InfraIdQueryParam {
Expand Down
Loading

0 comments on commit c58e8bb

Please sign in to comment.