Skip to content

Commit 47e5a35

Browse files
committed
front: convert times from NGE to OSRD
Closes: #8389
1 parent 90e655f commit 47e5a35

File tree

1 file changed

+69
-14
lines changed
  • front/src/applications/operationalStudies/components/MacroEditor

1 file changed

+69
-14
lines changed

front/src/applications/operationalStudies/components/MacroEditor/ngeToOsrd.ts

+69-14
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@ import {
44
type TrainScheduleResult,
55
} from 'common/api/osrdEditoastApi';
66
import type { AppDispatch } from 'store';
7+
import { formatToIsoDate } from 'utils/date';
8+
import { calculateTimeDifferenceInSeconds, formatDurationAsISO8601 } from 'utils/timeManipulation';
79

810
import nodeStore from './nodeStore';
9-
import type { NetzgrafikDto, NGEEvent, TrainrunSection, Node, Trainrun } from './types';
11+
import type { NetzgrafikDto, NGEEvent, TrainrunSection, Node, TimeLock, Trainrun } from './types';
1012

1113
const createdTrainrun = new Map<number, number>();
1214

@@ -16,14 +18,9 @@ const getTrainrunSectionsByTrainrunId = (trainrunSections: TrainrunSection[], tr
1618
const getNodeById = (nodes: Node[], nodeId: number | string) =>
1719
nodes.find((node) => node.id === nodeId);
1820

19-
// TODO: add a dynamic values when available
20-
const DEFAULT_PAYLOAD: Pick<
21-
TrainScheduleBase,
22-
'constraint_distribution' | 'rolling_stock_name' | 'start_time'
23-
> = {
21+
const DEFAULT_PAYLOAD: Pick<TrainScheduleBase, 'constraint_distribution' | 'rolling_stock_name'> = {
2422
constraint_distribution: 'STANDARD',
2523
rolling_stock_name: '',
26-
start_time: '2024-07-15T08:00:00+02:00',
2724
};
2825

2926
const createPathItemFromNode = (node: Node, index: number) => {
@@ -35,10 +32,24 @@ const createPathItemFromNode = (node: Node, index: number) => {
3532
};
3633
};
3734

35+
const getTimeLockDate = (
36+
timeLock: TimeLock,
37+
startTimeLock: TimeLock,
38+
startDate: Date
39+
): Date | null => {
40+
if (timeLock.time === null) return null;
41+
const offset = timeLock.consecutiveTime! - startTimeLock.consecutiveTime!;
42+
return new Date(startDate.getTime() + offset * 60 * 1000);
43+
};
44+
45+
const formatDateDifference = (start: Date, stop: Date) =>
46+
formatDurationAsISO8601(calculateTimeDifferenceInSeconds(start, stop));
47+
3848
const createTrainSchedulePayload = (
3949
trainrunSections: TrainrunSection[],
4050
nodes: Node[],
41-
trainrun: Trainrun
51+
trainrun: Trainrun,
52+
oldStartDate: Date
4253
) => {
4354
// TODO: check that the trainrunSections format is still compatible
4455
const path = trainrunSections.flatMap((section, index) => {
@@ -47,15 +58,52 @@ const createTrainSchedulePayload = (
4758
if (!sourceNode || !targetNode) return [];
4859
const originPathItem = createPathItemFromNode(sourceNode, index);
4960
if (index === trainrunSections.length - 1) {
50-
const destinationPathItem = createPathItemFromNode(targetNode, index);
61+
const destinationPathItem = createPathItemFromNode(targetNode, index + 1);
5162
return [originPathItem, destinationPathItem];
5263
}
5364
return [originPathItem];
5465
});
5566

67+
// The departure time of the first section is guaranteed to be non-null
68+
const startTimeLock = trainrunSections[0].sourceDeparture;
69+
const startDate = new Date(oldStartDate);
70+
startDate.setMinutes(startTimeLock.time!, 0, 0);
71+
72+
const schedule = trainrunSections.flatMap((section, index) => {
73+
const nextSection = trainrunSections[index + 1];
74+
75+
// TODO: extract isNonStopTransit from transitions
76+
let arrival = getTimeLockDate(section.targetArrival, startTimeLock, startDate);
77+
const departure = nextSection
78+
? getTimeLockDate(nextSection.sourceDeparture, startTimeLock, startDate)
79+
: null;
80+
if (!arrival && !departure) {
81+
return [];
82+
}
83+
84+
// If missing arrival time, default to a zero stop duration
85+
arrival = arrival || departure!;
86+
87+
let stopFor = null;
88+
if (departure) {
89+
stopFor = formatDateDifference(departure, arrival);
90+
} else if (!nextSection) {
91+
// Arrival needs to explicitly stop the train
92+
stopFor = formatDurationAsISO8601(0);
93+
}
94+
95+
return {
96+
at: `${section.targetNodeId}-${index + 1}`,
97+
arrival: formatDateDifference(arrival, startDate),
98+
stop_for: stopFor,
99+
};
100+
});
101+
56102
return {
57-
path,
58103
train_name: trainrun.name,
104+
start_time: formatToIsoDate(startDate),
105+
path,
106+
schedule,
59107
};
60108
};
61109

@@ -83,13 +131,19 @@ const handleTrainrunOperation = async ({
83131
);
84132
switch (type) {
85133
case 'create': {
134+
const startDate = new Date();
86135
const newTrainSchedules = await dispatch(
87136
osrdEditoastApi.endpoints.postV2TimetableByIdTrainSchedule.initiate({
88137
id: timeTableId,
89138
body: [
90139
{
91140
...DEFAULT_PAYLOAD,
92-
...createTrainSchedulePayload(trainrunSectionsByTrainrunId, nodes, trainrun),
141+
...createTrainSchedulePayload(
142+
trainrunSectionsByTrainrunId,
143+
nodes,
144+
trainrun,
145+
startDate
146+
),
93147
},
94148
],
95149
})
@@ -116,14 +170,15 @@ const handleTrainrunOperation = async ({
116170
id: trainrunIdToUpdate,
117171
})
118172
).unwrap();
173+
const startDate = new Date(trainSchedule.start_time);
119174
const newTrainSchedule = await dispatch(
120175
osrdEditoastApi.endpoints.putV2TrainScheduleById.initiate({
121176
id: trainrunIdToUpdate,
122177
trainScheduleForm: {
123178
...trainSchedule,
124-
...createTrainSchedulePayload(trainrunSectionsByTrainrunId, nodes, trainrun),
125-
// TODO: convert NGE times to OSRD schedule
126-
schedule: [],
179+
...createTrainSchedulePayload(trainrunSectionsByTrainrunId, nodes, trainrun, startDate),
180+
// Reset margins because they contain references to path items
181+
margins: undefined,
127182
},
128183
})
129184
).unwrap();

0 commit comments

Comments
 (0)