1
1
import { osrdEditoastApi , type TrainScheduleBase } from 'common/api/osrdEditoastApi' ;
2
2
import type { AppDispatch } from 'store' ;
3
+ import { formatToIsoDate } from 'utils/date' ;
4
+ import { calculateTimeDifferenceInSeconds , formatDurationAsISO8601 } from 'utils/timeManipulation' ;
3
5
4
- import type { NetzgrafikDto , NGETrainrunEvent , TrainrunSection , Node , Trainrun } from './types' ;
6
+ import type {
7
+ NetzgrafikDto ,
8
+ NGETrainrunEvent ,
9
+ TrainrunSection ,
10
+ Node ,
11
+ TimeLock ,
12
+ Trainrun ,
13
+ } from './types' ;
5
14
6
15
const createdTrainrun = new Map < number , number > ( ) ;
7
16
@@ -11,14 +20,9 @@ const getTrainrunSectionsByTrainrunId = (trainrunSections: TrainrunSection[], tr
11
20
const getNodeById = ( nodes : Node [ ] , nodeId : number | string ) =>
12
21
nodes . find ( ( node ) => node . id === nodeId ) ;
13
22
14
- // TODO: add a dynamic values when available
15
- const DEFAULT_PAYLOAD : Pick <
16
- TrainScheduleBase ,
17
- 'constraint_distribution' | 'rolling_stock_name' | 'start_time'
18
- > = {
23
+ const DEFAULT_PAYLOAD : Pick < TrainScheduleBase , 'constraint_distribution' | 'rolling_stock_name' > = {
19
24
constraint_distribution : 'STANDARD' ,
20
25
rolling_stock_name : '' ,
21
- start_time : '2024-07-15T08:00:00+02:00' ,
22
26
} ;
23
27
24
28
const createPathItemFromNode = ( node : Node , index : number ) => {
@@ -30,10 +34,19 @@ const createPathItemFromNode = (node: Node, index: number) => {
30
34
} ;
31
35
} ;
32
36
37
+ const getTimeLockDate = ( timeLock : TimeLock , baseDate : Date ) : Date | null => {
38
+ if ( timeLock . time === null ) return null ;
39
+ return new Date ( baseDate . getTime ( ) + timeLock . consecutiveTime ! * 60 * 1000 ) ;
40
+ } ;
41
+
42
+ const formatDateDifference = ( start : Date , stop : Date ) =>
43
+ formatDurationAsISO8601 ( calculateTimeDifferenceInSeconds ( start , stop ) ) ;
44
+
33
45
const createTrainSchedulePayload = (
34
46
trainrunSections : TrainrunSection [ ] ,
35
47
nodes : Node [ ] ,
36
- trainrun : Trainrun
48
+ trainrun : Trainrun ,
49
+ startDate : Date
37
50
) => {
38
51
// TODO: check that the trainrunSections format is still compatible
39
52
const path = trainrunSections . flatMap ( ( section , index ) => {
@@ -42,15 +55,43 @@ const createTrainSchedulePayload = (
42
55
if ( ! sourceNode || ! targetNode ) return [ ] ;
43
56
const originPathItem = createPathItemFromNode ( sourceNode , index ) ;
44
57
if ( index === trainrunSections . length - 1 ) {
45
- const destinationPathItem = createPathItemFromNode ( targetNode , index ) ;
58
+ const destinationPathItem = createPathItemFromNode ( targetNode , index + 1 ) ;
46
59
return [ originPathItem , destinationPathItem ] ;
47
60
}
48
61
return [ originPathItem ] ;
49
62
} ) ;
50
63
64
+ const baseDate = new Date ( startDate ) ;
65
+ baseDate . setMinutes ( 0 , 0 , 0 ) ;
66
+
67
+ // The departure time of the first section is guaranteed to be non-null
68
+ const startTime = getTimeLockDate ( trainrunSections [ 0 ] . sourceDeparture , baseDate ) ! ;
69
+
70
+ const schedule = trainrunSections . flatMap ( ( section , index ) => {
71
+ const nextSection = trainrunSections [ index + 1 ] ;
72
+
73
+ // TODO: extract isNonStopTransit from transitions
74
+ let arrival = getTimeLockDate ( section . targetArrival , baseDate ) ;
75
+ const departure = nextSection ? getTimeLockDate ( nextSection . sourceDeparture , baseDate ) : null ;
76
+ if ( ! arrival && ! departure ) {
77
+ return [ ] ;
78
+ }
79
+
80
+ // If missing arrival time, default to a zero stop duration
81
+ arrival = arrival || departure ! ;
82
+
83
+ return {
84
+ at : `${ section . targetNodeId } -${ index + 1 } ` ,
85
+ arrival : formatDateDifference ( startTime , arrival ) ,
86
+ stop_for : departure ? formatDateDifference ( arrival , departure ) : null ,
87
+ } ;
88
+ } ) ;
89
+
51
90
return {
52
- path,
53
91
train_name : trainrun . name ,
92
+ start_time : formatToIsoDate ( startTime ) ,
93
+ path,
94
+ schedule,
54
95
} ;
55
96
} ;
56
97
@@ -74,13 +115,19 @@ const handleOperation = async ({
74
115
) ;
75
116
switch ( type ) {
76
117
case 'create' : {
118
+ const startDate = new Date ( ) ;
77
119
const newTrainSchedules = await dispatch (
78
120
osrdEditoastApi . endpoints . postV2TimetableByIdTrainSchedule . initiate ( {
79
121
id : timeTableId ,
80
122
body : [
81
123
{
82
124
...DEFAULT_PAYLOAD ,
83
- ...createTrainSchedulePayload ( trainrunSectionsByTrainrunId , nodes , trainrun ) ,
125
+ ...createTrainSchedulePayload (
126
+ trainrunSectionsByTrainrunId ,
127
+ nodes ,
128
+ trainrun ,
129
+ startDate
130
+ ) ,
84
131
} ,
85
132
] ,
86
133
} )
@@ -105,14 +152,13 @@ const handleOperation = async ({
105
152
id : trainrunIdToUpdate ,
106
153
} )
107
154
) . unwrap ( ) ;
155
+ const startDate = new Date ( trainSchedule . start_time ) ;
108
156
await dispatch (
109
157
osrdEditoastApi . endpoints . putV2TrainScheduleById . initiate ( {
110
158
id : trainrunIdToUpdate ,
111
159
trainScheduleForm : {
112
160
...trainSchedule ,
113
- ...createTrainSchedulePayload ( trainrunSectionsByTrainrunId , nodes , trainrun ) ,
114
- // TODO: convert NGE times to OSRD schedule
115
- schedule : [ ] ,
161
+ ...createTrainSchedulePayload ( trainrunSectionsByTrainrunId , nodes , trainrun , startDate ) ,
116
162
} ,
117
163
} )
118
164
) . unwrap ( ) ;
0 commit comments