@@ -160,6 +160,130 @@ class ChallengePhaseHelper {
160
160
}
161
161
}
162
162
163
+ async populatePhasesForChallengeCreation ( phases , startDate , timelineTemplateId ) {
164
+ if ( _ . isUndefined ( timelineTemplateId ) ) {
165
+ throw new errors . BadRequestError ( `Invalid timeline template ID: ${ timelineTemplateId } ` ) ;
166
+ }
167
+ const { timelineTempate } = await this . getTemplateAndTemplateMap ( timelineTemplateId ) ;
168
+ const { phaseDefinitionMap } = await this . getPhaseDefinitionsAndMap ( ) ;
169
+ const finalPhases = _ . map ( timelineTempate , ( phaseFromTemplate ) => {
170
+ const phaseDefinition = phaseDefinitionMap . get ( phaseFromTemplate . phaseId ) ;
171
+ const phaseFromInput = _ . find ( phases , ( p ) => p . phaseId === phaseFromTemplate . phaseId ) ;
172
+ const phase = {
173
+ id : uuid ( ) ,
174
+ phaseId : phaseFromTemplate . phaseId ,
175
+ name : phaseDefinition . name ,
176
+ description : phaseDefinition . description ,
177
+ duration : _ . defaultTo ( _ . get ( phaseFromInput , "duration" ) , phaseFromTemplate . defaultDuration ) ,
178
+ isOpen : false ,
179
+ predecessor : phaseFromTemplate . predecessor ,
180
+ constraints : _ . defaultTo ( _ . get ( phaseFromInput , "constraints" ) , [ ] ) ,
181
+ scheduledStartDate : undefined ,
182
+ scheduledEndDate : undefined ,
183
+ actualStartDate : undefined ,
184
+ actualEndDate : undefined ,
185
+ } ;
186
+ if ( _ . isUndefined ( phase . predecessor ) ) {
187
+ if ( _ . isUndefined ( _ . get ( phaseFromInput , "scheduledStartDate" ) ) ) {
188
+ phase . scheduledStartDate = moment ( startDate ) . toDate ( ) ;
189
+ } else {
190
+ phase . scheduledStartDate = moment ( _ . get ( phaseFromInput , "scheduledStartDate" ) ) . toDate ( ) ;
191
+ }
192
+ phase . scheduledEndDate = moment ( phase . scheduledStartDate )
193
+ . add ( phase . duration , "seconds" )
194
+ . toDate ( ) ;
195
+ }
196
+ return phase ;
197
+ } ) ;
198
+ for ( let phase of finalPhases ) {
199
+ if ( _ . isUndefined ( phase . predecessor ) ) {
200
+ continue ;
201
+ }
202
+ const precedecessorPhase = _ . find ( finalPhases , {
203
+ phaseId : phase . predecessor ,
204
+ } ) ;
205
+ if ( phase . name === "Iterative Review Phase" ) {
206
+ phase . scheduledStartDate = precedecessorPhase . scheduledStartDate ;
207
+ } else {
208
+ phase . scheduledStartDate = precedecessorPhase . scheduledEndDate ;
209
+ }
210
+ phase . scheduledEndDate = moment ( phase . scheduledStartDate )
211
+ . add ( phase . duration , "seconds" )
212
+ . toDate ( ) ;
213
+ }
214
+ return finalPhases ;
215
+ }
216
+
217
+ async populatePhasesForChallengeUpdate (
218
+ challengePhases ,
219
+ newPhases ,
220
+ timelineTemplateId ,
221
+ isBeingActivated
222
+ ) {
223
+ const { timelineTempate, timelineTemplateMap } = await this . getTemplateAndTemplateMap (
224
+ timelineTemplateId
225
+ ) ;
226
+ const { phaseDefinitionMap } = await this . getPhaseDefinitionsAndMap ( ) ;
227
+
228
+ const updatedPhases = _ . map ( challengePhases , ( phase ) => {
229
+ const phaseFromTemplate = timelineTemplateMap . get ( phase . phaseId ) ;
230
+ const phaseDefinition = phaseDefinitionMap . get ( phase . phaseId ) ;
231
+ const updatedPhase = {
232
+ ...phase ,
233
+ predecessor : phaseFromTemplate . predecessor ,
234
+ description : phaseDefinition . description ,
235
+ } ;
236
+ if ( ! _ . isUndefined ( phase . actualEndDate ) ) {
237
+ return updatedPhase ;
238
+ }
239
+ if ( phase . name === "Iterative Review Phase" ) {
240
+ return updatedPhase ;
241
+ }
242
+ const newPhase = _ . find ( newPhases , ( p ) => p . phaseId === phase . phaseId ) ;
243
+ if ( _ . isUndefined ( newPhase ) && ! isBeingActivated ) {
244
+ return updatedPhase ;
245
+ }
246
+ phase . duration = _ . defaultTo ( _ . get ( newPhase , "duration" ) , phase . duration ) ;
247
+ if ( _ . isUndefined ( phase . predecessor ) ) {
248
+ if (
249
+ isBeingActivated &&
250
+ moment (
251
+ _ . defaultTo ( _ . get ( newPhase , "scheduledStartDate" ) , phase . scheduledStartDate )
252
+ ) . isSameOrBefore ( moment ( ) )
253
+ ) {
254
+ phase . isOpen = true ;
255
+ phase . scheduledStartDate = moment ( ) . toDate ( ) ;
256
+ phase . actualStartDate = phase . scheduledStartDate ;
257
+ } else if ( phase . isOpen === false && ! _ . isUndefined ( newPhase . scheduledStartDate ) ) {
258
+ phase . scheduledStartDate = moment ( newPhase . scheduledStartDate ) . toDate ( ) ;
259
+ }
260
+ phase . scheduledEndDate = moment ( phase . scheduledStartDate )
261
+ . add ( phase . duration , "seconds" )
262
+ . toDate ( ) ;
263
+ }
264
+ if ( ! _ . isUndefined ( newPhase ) && ! _ . isUndefined ( newPhase . constraints ) ) {
265
+ phase . constraints = newPhase . constraints ;
266
+ }
267
+ return updatedPhase ;
268
+ } ) ;
269
+ for ( let phase of updatedPhases ) {
270
+ if ( _ . isUndefined ( phase . predecessor ) ) {
271
+ continue ;
272
+ }
273
+ if ( phase . name === "Iterative Review Phase" ) {
274
+ continue ;
275
+ }
276
+ const precedecessorPhase = _ . find ( updatedPhases , {
277
+ phaseId : phase . predecessor ,
278
+ } ) ;
279
+ phase . scheduledStartDate = precedecessorPhase . scheduledEndDate ;
280
+ phase . scheduledEndDate = moment ( phase . scheduledStartDate )
281
+ . add ( phase . duration , "seconds" )
282
+ . toDate ( ) ;
283
+ }
284
+ return updatedPhases ;
285
+ }
286
+
163
287
async validatePhases ( phases ) {
164
288
if ( ! phases || phases . length === 0 ) {
165
289
return ;
0 commit comments