Skip to content

Commit 99aa5d0

Browse files
authored
editoast: adapt level crossing occupancy endpoint with new exceptions (#15930)
Part of #15202 This PR adapt the `/level_crossing_occupancy`endpoint to use the new exceptions table It also requires the timetable_id as a parameter, as exceptions are now related to a timetable and not just to a train schedule > [!NOTE] > This PR targets a feature branch and may contain all its commits, as it has not been rebased yet. Only the last commit need to be reviewed. Signed-off-by: Egor <egor@berezify.fr>
1 parent c84a410 commit 99aa5d0

File tree

7 files changed

+38
-7
lines changed

7 files changed

+38
-7
lines changed

editoast/openapi.yaml

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

editoast/src/models/train_schedule.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -823,7 +823,7 @@ mod tests {
823823

824824
let paced_train = create_paced_train(vec![]);
825825
let occurrences: Vec<_> = paced_train
826-
.iter_occurrences_v2(&[exception_1.clone()])
826+
.iter_occurrences_v2(std::slice::from_ref(&exception_1))
827827
.collect();
828828

829829
assert_eq!(occurrences.len(), 4);

editoast/src/views/level_crossing_occupancy.rs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use core_client::pathfinding::TrackRange;
2424
use core_client::simulation::ReportTrain;
2525
use database::DbConnection;
2626
use editoast_derive::EditoastError;
27+
use editoast_models::TrainScheduleException;
2728
use editoast_models::prelude::*;
2829
use editoast_models::rolling_stock::RollingStock;
2930
use itertools::Itertools;
@@ -61,6 +62,7 @@ pub(in crate::views) struct LevelCrossingOccupancyForm {
6162
train_ids: Vec<i64>,
6263
level_crossing_ids: Vec<Identifier>,
6364
infra_id: i64,
65+
timetable_id: i64,
6466
electrical_profile_set_id: Option<i64>,
6567
}
6668

@@ -98,6 +100,7 @@ pub(in crate::views) async fn occupancy(
98100
train_ids,
99101
level_crossing_ids,
100102
infra_id,
103+
timetable_id,
101104
electrical_profile_set_id,
102105
}): Json<LevelCrossingOccupancyForm>,
103106
) -> Result<Json<HashMap<Identifier, Vec<LevelCrossingOccupancy>>>> {
@@ -137,17 +140,31 @@ pub(in crate::views) async fn occupancy(
137140
.await?;
138141

139142
let trains: Vec<TrainSchedule> =
140-
TrainSchedule::retrieve_batch_or_fail(conn, train_ids, |missing| {
143+
TrainSchedule::retrieve_batch_or_fail(conn, train_ids.clone(), |missing| {
141144
LevelCrossingError::TrainBatchNotFound {
142145
count: missing.len(),
143146
}
144147
})
145148
.await?;
146149

150+
let mut exceptions = TrainScheduleException::retrieve_exceptions_by_train_schedules(
151+
conn,
152+
timetable_id,
153+
train_ids,
154+
)
155+
.await?
156+
.into_iter()
157+
.map_into::<schemas::TrainScheduleException>()
158+
.into_group_map_by(|e| e.timetable_id);
159+
147160
// Collect all occurrences from all trains
148161
let train_occurrences = trains
149162
.iter()
150-
.flat_map(|train| train.iter_occurrences())
163+
.flat_map(|train| {
164+
train
165+
.iter_occurrences_v2(&exceptions.remove(&train.id).unwrap_or_default())
166+
.collect::<Vec<_>>()
167+
})
151168
.collect_vec();
152169

153170
// Extract train schedules for simulation
@@ -351,7 +368,7 @@ mod tests {
351368
use super::*;
352369
use crate::models::fixtures::create_fast_rolling_stock;
353370
use crate::models::fixtures::create_small_infra;
354-
use crate::models::fixtures::create_train_schedule_set;
371+
use crate::models::fixtures::create_timetable_with_train_schedule_set;
355372
use crate::views::test_app::TestAppBuilder;
356373
use crate::views::test_app::TestResponse;
357374
use chrono::TimeDelta;
@@ -528,7 +545,8 @@ mod tests {
528545
let small_infra = create_small_infra(&mut db_pool.get_ok()).await;
529546
let rolling_stock =
530547
create_fast_rolling_stock(&mut db_pool.get_ok(), "simulation_rolling_stock").await;
531-
let train_schedule_set = create_train_schedule_set(&mut db_pool.get_ok()).await;
548+
let (timetable, train_schedule_set) =
549+
create_timetable_with_train_schedule_set(&mut db_pool.get_ok()).await;
532550

533551
// Create level crossing
534552
let level_crossing = LevelCrossingModel::default()
@@ -570,6 +588,7 @@ mod tests {
570588
train_ids: vec![train.id],
571589
level_crossing_ids: vec![level_crossing.obj_id.clone().into()],
572590
infra_id: small_infra.id,
591+
timetable_id: timetable.id,
573592
electrical_profile_set_id: None,
574593
});
575594

front/src/applications/operationalStudies/views/Scenario/components/SimulationResults/SimulationResults.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,7 @@ const SimulationResults = ({
325325
>
326326
<div data-testid="chronogram" className="simulation-chronogram">
327327
<ChronogramWrapper
328+
timetableId={timetableId}
328329
timetableItemsWithDetails={timetableItemsWithDetails}
329330
chronogramHeight={chronogramHeight}
330331
/>

front/src/common/api/generatedEditoastApi.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1931,6 +1931,7 @@ export type PostLevelCrossingOccupancyApiArg = {
19311931
electrical_profile_set_id?: number | null;
19321932
infra_id: number;
19331933
level_crossing_ids: Identifier[];
1934+
timetable_id: number;
19341935
train_ids: number[];
19351936
};
19361937
};

front/src/modules/simulationResult/components/Chronogram/ChronogramWrapper.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,17 @@ import useLevelCrossingsWithChronogram from './useLevelCrossingsWithChronogram';
77
const CHRONOGRAM_FOOTER_HEIGHT = 39;
88

99
type ChronogramWrapperProps = {
10+
timetableId: number;
1011
timetableItemsWithDetails: TimetableItemWithDetails[];
1112
chronogramHeight: number;
1213
};
1314

1415
const ChronogramWrapper = ({
16+
timetableId,
1517
timetableItemsWithDetails,
1618
chronogramHeight,
1719
}: ChronogramWrapperProps) => {
18-
const { levelCrossingData, timeOrigin } = useLevelCrossingsWithChronogram({
20+
const { levelCrossingData, timeOrigin } = useLevelCrossingsWithChronogram(timetableId, {
1921
trains: timetableItemsWithDetails,
2022
});
2123

front/src/modules/simulationResult/components/Chronogram/useLevelCrossingsWithChronogram.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ type UseLevelCrossingsWithChronogramProps = {
1515
trains: TimetableItemWithDetails[];
1616
};
1717

18-
const useLevelCrossingsWithChronogram = ({ trains }: UseLevelCrossingsWithChronogramProps) => {
18+
const useLevelCrossingsWithChronogram = (
19+
timetableId: number,
20+
{ trains }: UseLevelCrossingsWithChronogramProps
21+
) => {
1922
const infraId = useInfraID();
2023
const dispatch = useAppDispatch();
2124

@@ -51,6 +54,7 @@ const useLevelCrossingsWithChronogram = ({ trains }: UseLevelCrossingsWithChrono
5154
body: {
5255
infra_id: infraId,
5356
train_ids: trainIds,
57+
timetable_id: timetableId,
5458
level_crossing_ids: levelCrossingsIds.ids,
5559
},
5660
}

0 commit comments

Comments
 (0)